home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Source / GNU / cc / cp-search.c < prev    next >
C/C++ Source or Header  |  1994-01-17  |  111KB  |  3,767 lines

  1. /* Breadth-first and depth-first routines for
  2.    searching multiple-inheritance lattice for GNU C++.
  3.    Copyright (C) 1987, 1989, 1992, 1993 Free Software Foundation, Inc.
  4.    Contributed by Michael Tiemann (tiemann@cygnus.com)
  5.  
  6. This file is part of GNU CC.
  7.  
  8. GNU CC is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2, or (at your option)
  11. any later version.
  12.  
  13. GNU CC is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with GNU CC; see the file COPYING.  If not, write to
  20. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  21.  
  22. /* High-level class interface. */
  23.  
  24. #include "config.h"
  25. #include "tree.h"
  26. #include <stdio.h>
  27. #include "cp-tree.h"
  28. #include "obstack.h"
  29. #include "flags.h"
  30.  
  31. #define obstack_chunk_alloc xmalloc
  32. #define obstack_chunk_free free
  33.  
  34. void init_search ();
  35. extern struct obstack *current_obstack;
  36.  
  37. #include "stack.h"
  38.  
  39. /* Obstack used for remembering decision points of breadth-first.  */
  40. static struct obstack search_obstack;
  41.  
  42. /* Methods for pushing and popping objects to and from obstacks.  */
  43. struct stack_level *
  44. push_stack_level (obstack, tp, size)
  45.      struct obstack *obstack;
  46.      char *tp;  /* Sony NewsOS 5.0 compiler doesn't like void * here.  */
  47.      int size;
  48. {
  49.   struct stack_level *stack;
  50.   obstack_grow (obstack, tp, size);
  51.   stack = (struct stack_level *) ((char*)obstack_next_free (obstack) - size);
  52.   obstack_finish (obstack);
  53.   stack->obstack = obstack;
  54.   stack->first = (tree *) obstack_base (obstack);
  55.   stack->limit = obstack_room (obstack) / sizeof (tree *);
  56.   return stack;
  57. }
  58.  
  59. struct stack_level *
  60. pop_stack_level (stack)
  61.      struct stack_level *stack;
  62. {
  63.   struct stack_level *tem = stack;
  64.   struct obstack *obstack = tem->obstack;
  65.   stack = tem->prev;
  66.   obstack_free (obstack, tem);
  67.   return stack;
  68. }
  69.  
  70. #define search_level stack_level
  71. static struct search_level *search_stack;
  72.  
  73. static tree lookup_field_1 ();
  74. static int lookup_fnfields_1 ();
  75. static void dfs_walk ();
  76. static int markedp ();
  77. static void dfs_unmark ();
  78. static void dfs_init_vbase_pointers ();
  79.  
  80. static tree vbase_types;
  81. static tree vbase_decl, vbase_decl_ptr;
  82. static tree vbase_decl_ptr_intermediate;
  83. static tree vbase_init_result;
  84.  
  85. /* Allocate a level of searching.  */
  86. static struct search_level *
  87. push_search_level (stack, obstack)
  88.      struct stack_level *stack;
  89.      struct obstack *obstack;
  90. {
  91.   struct search_level tem;
  92.  
  93.   tem.prev = stack;
  94.   return push_stack_level (obstack, (char *)&tem, sizeof (tem));
  95. }
  96.  
  97. /* Discard a level of search allocation.  */
  98. static struct search_level *
  99. pop_search_level (obstack)
  100.      struct stack_level *obstack;
  101. {
  102.   register struct search_level *stack = pop_stack_level (obstack);
  103.  
  104.   return stack;
  105. }
  106.  
  107. /* Search memoization.  */
  108. struct type_level
  109. {
  110.   struct stack_level base;
  111.  
  112.   /* First object allocated in obstack of entries.  */
  113.   char *entries;
  114.  
  115.   /* Number of types memoized in this context.  */
  116.   int len;
  117.  
  118.   /* Type being memoized; save this if we are saving
  119.      memoized contexts.  */
  120.   tree type;
  121. };
  122.  
  123. /* Obstack used for memoizing member and member function lookup.  */
  124.  
  125. static struct obstack type_obstack, type_obstack_entries;
  126. static struct type_level *type_stack;
  127. static tree _vptr_name;
  128.  
  129. /* Make things that look like tree nodes, but allocate them
  130.    on type_obstack_entries.  */
  131. static int my_tree_node_counter;
  132. static tree my_tree_cons (), my_build_string ();
  133.  
  134. extern int flag_memoize_lookups, flag_save_memoized_contexts;
  135.  
  136. /* Variables for gathering statistics.  */
  137. static int my_memoized_entry_counter;
  138. static int memoized_fast_finds[2], memoized_adds[2], memoized_fast_rejects[2];
  139. static int memoized_fields_searched[2];
  140. static int n_fields_searched;
  141. static int n_calls_lookup_field, n_calls_lookup_field_1;
  142. static int n_calls_lookup_fnfields, n_calls_lookup_fnfields_1;
  143. static int n_calls_get_base_type;
  144. static int n_outer_fields_searched;
  145. static int n_contexts_saved;
  146.  
  147. /* Local variables to help save memoization contexts.  */
  148. static tree prev_type_memoized;
  149. static struct type_level *prev_type_stack;
  150.  
  151. #if NEW_CLASS_SCOPING
  152. /* This list is used by push_class_decls to know what decls need to
  153.    be pushed into class scope.  */
  154. static tree closed_envelopes = NULL_TREE;
  155. #endif
  156.  
  157. /* Allocate a level of type memoization context.  */
  158. static struct type_level *
  159. push_type_level (stack, obstack)
  160.      struct stack_level *stack;
  161.      struct obstack *obstack;
  162. {
  163.   struct type_level tem;
  164.  
  165.   tem.base.prev = stack;
  166.  
  167.   obstack_finish (&type_obstack_entries);
  168.   tem.entries = (char *) obstack_base (&type_obstack_entries);
  169.   tem.len = 0;
  170.   tem.type = NULL_TREE;
  171.  
  172.   return (struct type_level *)push_stack_level (obstack, (char *)&tem, sizeof (tem));
  173. }
  174.  
  175. /* Discard a level of type memoization context.  */
  176.  
  177. static struct type_level *
  178. pop_type_level (stack)
  179.      struct type_level *stack;
  180. {
  181.   obstack_free (&type_obstack_entries, stack->entries);
  182.   return (struct type_level *)pop_stack_level ((struct stack_level *)stack);
  183. }
  184.  
  185. /* Make something that looks like a TREE_LIST, but
  186.    do it on the type_obstack_entries obstack.  */
  187. static tree
  188. my_tree_cons (purpose, value, chain)
  189.      tree purpose, value, chain;
  190. {
  191.   tree p = (tree)obstack_alloc (&type_obstack_entries, sizeof (struct tree_list));
  192.   ++my_tree_node_counter;
  193.   TREE_TYPE (p) = NULL_TREE;
  194.   ((HOST_WIDE_INT *)p)[3] = 0;
  195.   TREE_SET_CODE (p, TREE_LIST);
  196.   TREE_PURPOSE (p) = purpose;
  197.   TREE_VALUE (p) = value;
  198.   TREE_CHAIN (p) = chain;
  199.   return p;
  200. }
  201.  
  202. static tree
  203. my_build_string (str)
  204.      char *str;
  205. {
  206.   tree p = (tree)obstack_alloc (&type_obstack_entries, sizeof (struct tree_string));
  207.   ++my_tree_node_counter;
  208.   TREE_TYPE (p) = 0;
  209.   ((int *)p)[3] = 0;
  210.   TREE_SET_CODE (p, STRING_CST);
  211.   TREE_STRING_POINTER (p) = str;
  212.   TREE_STRING_LENGTH (p) = strlen (str);
  213.   return p;
  214. }
  215.  
  216. /* Memoizing machinery to make searches for multiple inheritance
  217.    reasonably efficient.  */
  218. #define MEMOIZE_HASHSIZE 8
  219. typedef struct memoized_entry
  220. {
  221.   struct memoized_entry *chain;
  222.   int uid;
  223.   tree data_members[MEMOIZE_HASHSIZE];
  224.   tree function_members[MEMOIZE_HASHSIZE];
  225. } *ME;
  226.  
  227. #define MEMOIZED_CHAIN(ENTRY) (((ME)ENTRY)->chain)
  228. #define MEMOIZED_UID(ENTRY) (((ME)ENTRY)->uid)
  229. #define MEMOIZED_FIELDS(ENTRY,INDEX) (((ME)ENTRY)->data_members[INDEX])
  230. #define MEMOIZED_FNFIELDS(ENTRY,INDEX) (((ME)ENTRY)->function_members[INDEX])
  231. /* The following is probably a lousy hash function.  */
  232. #define MEMOIZED_HASH_FN(NODE) (((long)(NODE)>>4)&(MEMOIZE_HASHSIZE - 1))
  233.  
  234. static struct memoized_entry *
  235. my_new_memoized_entry (chain)
  236.      struct memoized_entry *chain;
  237. {
  238.   struct memoized_entry *p =
  239.     (struct memoized_entry *)obstack_alloc (&type_obstack_entries,
  240.                         sizeof (struct memoized_entry));
  241.   bzero (p, sizeof (struct memoized_entry));
  242.   MEMOIZED_CHAIN (p) = chain;
  243.   MEMOIZED_UID (p) = ++my_memoized_entry_counter;
  244.   return p;
  245. }
  246.  
  247. /* Make an entry in the memoized table for type TYPE
  248.    that the entry for NAME is FIELD.  */
  249.  
  250. tree
  251. make_memoized_table_entry (type, name, function_p)
  252.      tree type, name;
  253.      int function_p;
  254. {
  255.   int index = MEMOIZED_HASH_FN (name);
  256.   tree entry, *prev_entry;
  257.  
  258.   memoized_adds[function_p] += 1;
  259.   if (CLASSTYPE_MTABLE_ENTRY (type) == 0)
  260.     {
  261.       obstack_ptr_grow (&type_obstack, type);
  262.       obstack_blank (&type_obstack, sizeof (struct memoized_entry *));
  263.       CLASSTYPE_MTABLE_ENTRY (type) = (char *)my_new_memoized_entry ((struct memoized_entry *)0);
  264.       type_stack->len++;
  265.       if (type_stack->len * 2 >= type_stack->base.limit)
  266.     my_friendly_abort (88);
  267.     }
  268.   if (function_p)
  269.     prev_entry = &MEMOIZED_FNFIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);
  270.   else
  271.     prev_entry = &MEMOIZED_FIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);
  272.  
  273.   entry = my_tree_cons (name, NULL_TREE, *prev_entry);
  274.   *prev_entry = entry;
  275.  
  276.   /* Don't know the error message to give yet.  */
  277.   TREE_TYPE (entry) = error_mark_node;
  278.  
  279.   return entry;
  280. }
  281.  
  282. /* When a new function or class context is entered, we build
  283.    a table of types which have been searched for members.
  284.    The table is an array (obstack) of types.  When a type is
  285.    entered into the obstack, its CLASSTYPE_MTABLE_ENTRY
  286.    field is set to point to a new record, of type struct memoized_entry.
  287.  
  288.    A non-NULL TREE_TYPE of the entry contains a visibility error message.
  289.  
  290.    The slots for the data members are arrays of tree nodes.
  291.    These tree nodes are lists, with the TREE_PURPOSE
  292.    of this list the known member name, and the TREE_VALUE
  293.    as the FIELD_DECL for the member.
  294.  
  295.    For member functions, the TREE_PURPOSE is again the
  296.    name of the member functions for that class,
  297.    and the TREE_VALUE of the list is a pairs
  298.    whose TREE_PURPOSE is a member functions of this name,
  299.    and whose TREE_VALUE is a list of known argument lists this
  300.    member function has been called with.  The TREE_TYPE of the pair,
  301.    if non-NULL, is an error message to print.  */
  302.  
  303. /* Tell search machinery that we are entering a new context, and
  304.    to update tables appropriately.
  305.  
  306.    TYPE is the type of the context we are entering, which can
  307.    be NULL_TREE if we are not in a class's scope.
  308.  
  309.    USE_OLD, if nonzero tries to use previous context.  */
  310. void
  311. push_memoized_context (type, use_old)
  312.      tree type;
  313.      int use_old;
  314. {
  315.   int len;
  316.   tree *tem;
  317.  
  318.   if (prev_type_stack)
  319.     {
  320.       if (use_old && prev_type_memoized == type)
  321.     {
  322. #ifdef GATHER_STATISTICS
  323.       n_contexts_saved++;
  324. #endif
  325.       type_stack = prev_type_stack;
  326.       prev_type_stack = 0;
  327.  
  328.       tem = &type_stack->base.first[0];
  329.       len = type_stack->len;
  330.       while (len--)
  331.         CLASSTYPE_MTABLE_ENTRY (tem[len*2]) = (char *)tem[len*2+1];
  332.       return;
  333.     }
  334.       /* Otherwise, need to pop old stack here.  */
  335.       type_stack = pop_type_level (prev_type_stack);
  336.       prev_type_memoized = 0;
  337.       prev_type_stack = 0;
  338.     }
  339.  
  340.   type_stack = push_type_level ((struct stack_level *)type_stack,
  341.                 &type_obstack);
  342.   type_stack->type = type;
  343. }
  344.  
  345. /* Tell search machinery that we have left a context.
  346.    We do not currently save these contexts for later use.
  347.    If we wanted to, we could not use pop_search_level, since
  348.    poping that level allows the data we have collected to
  349.    be clobbered; a stack of obstacks would be needed.  */
  350. void
  351. pop_memoized_context (use_old)
  352.      int use_old;
  353. {
  354.   int len;
  355.   tree *tem = &type_stack->base.first[0];
  356.  
  357.   if (! flag_save_memoized_contexts)
  358.     use_old = 0;
  359.   else if (use_old)
  360.     {
  361.       len = type_stack->len;
  362.       while (len--)
  363.     tem[len*2+1] = (tree)CLASSTYPE_MTABLE_ENTRY (tem[len*2]);
  364.  
  365.       prev_type_stack = type_stack;
  366.       prev_type_memoized = type_stack->type;
  367.     }
  368.  
  369.   if (flag_memoize_lookups)
  370.     {
  371.       len = type_stack->len;
  372.       while (len--)
  373.     CLASSTYPE_MTABLE_ENTRY (tem[len*2])
  374.       = (char *)MEMOIZED_CHAIN (CLASSTYPE_MTABLE_ENTRY (tem[len*2]));
  375.     }
  376.   if (! use_old)
  377.     type_stack = pop_type_level (type_stack);
  378.   else
  379.     type_stack = (struct type_level *)type_stack->base.prev;
  380. }
  381.  
  382. /* This is the newer recursive depth first search routine. */
  383. static tree
  384. get_binfo_recursive (binfo, is_private, parent, rval, rval_private_ptr, xtype,
  385.              friends, protect)
  386.      tree binfo, parent, rval, xtype, friends;
  387.      int *rval_private_ptr, protect, is_private;
  388. {
  389.   tree binfos;
  390.   int i, n_baselinks;
  391.  
  392.   if (BINFO_TYPE (binfo) == parent)
  393.     {
  394.       if (rval == NULL_TREE)
  395.     {
  396.       rval = binfo;
  397.       *rval_private_ptr = is_private;
  398.     }
  399.       else
  400.     {
  401.       /* I believe it is the case that this error is only an error
  402.          when used by someone that wants error messages printed.
  403.          Routines that call this one, that don't set protect want
  404.          the first one found, even if there are more.  */
  405.       if (protect)
  406.         {
  407.           /* Found two or more possible return values.  */
  408.           cp_error ("type `%T' is ambiguous base class for type `%T'",
  409.               parent, xtype);
  410.           rval = error_mark_node;
  411.         }
  412.     }
  413.       return rval;
  414.     }
  415.  
  416.   binfos = BINFO_BASETYPES (binfo);
  417.   n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  418.  
  419.   /* Process base types.  */
  420.   for (i = 0; i < n_baselinks; i++)
  421.     {
  422.       tree base_binfo = TREE_VEC_ELT (binfos, i);
  423.  
  424.       if (BINFO_MARKED (base_binfo) == 0)
  425.     {
  426.       int via_private = is_private || !TREE_VIA_PUBLIC (base_binfo);
  427.  
  428.       SET_BINFO_MARKED (base_binfo);
  429.  
  430.       if (via_private == 0)
  431.         ;
  432.       else if (protect == 0)
  433.         via_private = 0;
  434.       else if (protect == 1 && BINFO_TYPE (binfo) == current_class_type)
  435.         /* The immediate base class of the class we are in
  436.            does let its public members through.  */
  437.         via_private = 0;
  438. #ifndef NOJJG
  439.       else if (protect
  440.            && friends != NULL_TREE
  441.            && BINFO_TYPE (binfo) == xtype
  442.            && value_member (current_class_type, friends))
  443.         /* Friend types of the most derived type have access
  444.            to its baseclass pointers.  */
  445.         via_private = 0;
  446. #endif
  447.  
  448.       rval = get_binfo_recursive (base_binfo, via_private, parent, rval,
  449.                       rval_private_ptr, xtype, friends,
  450.                       protect);
  451.       if (rval == error_mark_node)
  452.         return rval;
  453.     }
  454.     }
  455.  
  456.   return rval;
  457. }
  458.  
  459. /* Return non-zero if PARENT is directly derived from TYPE.  By directly
  460.    we mean it's only one step up the inheritance lattice.  We check this
  461.    by walking horizontally across the types that TYPE directly inherits
  462.    from, to see if PARENT is among them.  This is used by get_binfo and
  463.    by compute_visibility.  */
  464. static int
  465. immediately_derived (parent, type)
  466.      tree parent, type;
  467. {
  468.   if (TYPE_BINFO (type))
  469.     {
  470.       tree binfos = BINFO_BASETYPES (TYPE_BINFO (type));
  471.       int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  472.  
  473.       for (i = 0; i < n_baselinks; i++)
  474.     {
  475.       tree base_binfo = TREE_VEC_ELT (binfos, i);
  476.  
  477.       if (parent == BINFO_TYPE (base_binfo))
  478.         return 1;
  479.     }
  480.     }
  481.   return 0;
  482. }
  483.  
  484. /* Check whether the type given in BINFO is derived from PARENT.  If
  485.    it isn't, return 0.  If it is, but the derivation is MI-ambiguous
  486.    AND protect != 0, emit an error message and return error_mark_node.
  487.  
  488.    Otherwise, if TYPE is derived from PARENT, return the actual base
  489.    information, unless a one of the protection violations below
  490.    occurs, in which case emit an error message and return error_mark_node.
  491.  
  492.    The below should be worded better.  It may not be exactly what the code
  493.    does, but there should be a lose correlation.  If you understand the code
  494.    well, please try and make the comments below more readable.
  495.  
  496.    If PROTECT is 1, then check if access to a public field of PARENT
  497.    would be private.
  498.  
  499.    If PROTECT is 2, then check if the given type is derived from
  500.    PARENT via private visibility rules.
  501.  
  502.    If PROTECT is 3, then immediately private baseclass is ok,
  503.    but deeper than that, check if private.  */
  504. tree
  505. get_binfo (parent, binfo, protect)
  506.      register tree parent, binfo;
  507.      int protect;
  508. {
  509.   tree xtype, type;
  510.   tree otype;
  511.   int head = 0, tail = 0;
  512.   int is_private = 0;
  513.   tree rval = NULL_TREE;
  514.   int rval_private = 0;
  515.   tree friends;
  516.  
  517. #ifdef GATHER_STATISTICS
  518.   n_calls_get_base_type++;
  519. #endif
  520.  
  521.   if (TREE_CODE (parent) == TREE_VEC)
  522.     parent = BINFO_TYPE (parent);
  523.   /* unions cannot participate in inheritance relationships */
  524.   else if (TREE_CODE (parent) == UNION_TYPE)
  525.     return NULL_TREE;
  526.   else if (TREE_CODE (parent) != RECORD_TYPE)
  527.     my_friendly_abort (89);
  528.  
  529.   parent = TYPE_MAIN_VARIANT (parent);
  530.  
  531.   if (TREE_CODE (binfo) == TREE_VEC)
  532.     type = BINFO_TYPE (binfo);
  533.   else if (TREE_CODE (binfo) == RECORD_TYPE)
  534.     {
  535.       type = binfo;
  536.       binfo = TYPE_BINFO (type);
  537.     }
  538.   else my_friendly_abort (90);
  539.   xtype = type;
  540.   friends = current_class_type ? CLASSTYPE_FRIEND_CLASSES (type) : NULL_TREE;
  541.  
  542.   rval = get_binfo_recursive (binfo, is_private, parent, rval, &rval_private,
  543.                   xtype, friends, protect);
  544.  
  545.   dfs_walk (binfo, dfs_unmark, markedp);
  546.  
  547.   if (rval && protect && rval_private)
  548.     {
  549.       if (protect == 3 && immediately_derived (parent, xtype))
  550.     return rval;
  551.       cp_error ("type `%T' is derived from private `%T'", xtype, parent);
  552.       return error_mark_node;
  553.     }
  554.  
  555. #ifdef OBJCPLUS
  556.   if (!rval)
  557.     {
  558.       if (objc_comptypes (parent, type, 1) == 1)
  559.     return parent;
  560.     }
  561. #endif
  562.  
  563.   return rval;
  564. }
  565.  
  566. /* This is the newer depth first get_base_distance routine.  */
  567. static
  568. get_base_distance_recursive (binfo, depth, is_private, basetype_path, rval,
  569.                  rval_private_ptr, new_binfo_ptr, parent, path_ptr,
  570.                  protect, via_virtual_ptr, via_virtual)
  571.      tree binfo, basetype_path, *new_binfo_ptr, parent, *path_ptr;
  572.      int *rval_private_ptr, depth, is_private, rval, protect, *via_virtual_ptr,
  573.        via_virtual;
  574. {
  575.   tree binfos;
  576.   int i, n_baselinks;
  577.  
  578.   if (BINFO_TYPE (binfo) == parent || binfo == parent)
  579.     {
  580.       if (rval == -1)
  581.     {
  582.       rval = depth;
  583.       *rval_private_ptr = is_private;
  584.       *new_binfo_ptr = binfo;
  585.       *via_virtual_ptr = via_virtual;
  586.     }
  587.       else
  588.     {
  589.       int same_object = tree_int_cst_equal (BINFO_OFFSET (*new_binfo_ptr),
  590.                         BINFO_OFFSET (binfo));
  591.  
  592.       if (*via_virtual_ptr && via_virtual==0)
  593.         {
  594.           *rval_private_ptr = is_private;
  595.           *new_binfo_ptr = binfo;
  596.           *via_virtual_ptr = via_virtual;
  597.         }
  598.       else if (same_object)
  599.         {
  600.           /* Note, this should probably succeed to find, and
  601.          override the old one if the old one was private and
  602.          this one isn't.  */
  603.           return rval;
  604.         }
  605.  
  606.       rval = -2;
  607.     }
  608.       return rval;
  609.     }
  610.  
  611.   binfos = BINFO_BASETYPES (binfo);
  612.   n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  613.   depth += 1;
  614.  
  615.   /* Process base types.  */
  616.   for (i = 0; i < n_baselinks; i++)
  617.     {
  618.       tree base_binfo = TREE_VEC_ELT (binfos, i);
  619.  
  620.       if (BINFO_MARKED (base_binfo) == 0)
  621.     {
  622.       int via_private = is_private || !TREE_VIA_PUBLIC (base_binfo);
  623.       int was;
  624.  
  625.       /* When searching for a non-virtual, we cannot mark
  626.          virtually found binfos. */
  627.       if (!via_virtual)
  628.         SET_BINFO_MARKED (base_binfo);
  629.  
  630.       if (via_private == 0)
  631.         ;
  632.       else if (protect == 0)
  633.         via_private = 0;
  634.  
  635. #define WATCH_VALUES(rval, via_private) (rval == -1 ? 3 : via_private)
  636.  
  637.       was = WATCH_VALUES (rval, *via_virtual_ptr);
  638.       rval = get_base_distance_recursive (base_binfo, depth, via_private,
  639.                           binfo, rval, rval_private_ptr,
  640.                           new_binfo_ptr, parent, path_ptr,
  641.                           protect, via_virtual_ptr,
  642.                           TREE_VIA_VIRTUAL (base_binfo)|via_virtual);
  643.       /* watch for updates, only update, if path is good. */
  644.       if (path_ptr && WATCH_VALUES (rval, *via_virtual_ptr) != was)
  645.         BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;
  646.       if (rval == -2 && *via_virtual_ptr == 0)
  647.         return rval;
  648.  
  649. #undef WATCH_VALUES
  650.  
  651.     }
  652.     }
  653.  
  654.   return rval;
  655. }
  656.  
  657. /* Return the number of levels between type PARENT and the type given
  658.    in BINFO, following the leftmost path to PARENT not found along a
  659.    virtual path, if there are no real PARENTs (all come from virtual
  660.    base classes), then follow the leftmost path to PARENT.
  661.  
  662.    Return -1 if TYPE is not derived from PARENT.
  663.    Return -2 if PARENT is an ambiguous base class of TYPE.
  664.    Return -3 if PARENT is private to TYPE, and protect is non-zero.
  665.  
  666.    If PATH_PTR is non-NULL, then also build the list of types
  667.    from PARENT to TYPE, with TREE_VIA_VIRUAL and TREE_VIA_PUBLIC
  668.    set.
  669.  
  670.    PARENT can also be a binfo, in which case that exact parent is found
  671.    and no other.  convert_pointer_to_real uses this functionality.
  672.  
  673.    Code in prepare_fresh_vtable relies upon the path being built even
  674.    when -2 is returned.  */
  675.  
  676. int
  677. get_base_distance (parent, binfo, protect, path_ptr)
  678.      register tree parent, binfo;
  679.      int protect;
  680.      tree *path_ptr;
  681. {
  682.   int head, tail;
  683.   int is_private = 0;
  684.   int rval;
  685.   int depth = 0;
  686.   int rval_private = 0;
  687.   tree type, basetype_path = NULL_TREE;
  688.   tree friends;
  689.   tree new_binfo = NULL_TREE;
  690.   int via_virtual;
  691.  
  692.   if (TREE_CODE (parent) != TREE_VEC)
  693.     parent = TYPE_MAIN_VARIANT (parent);
  694.  
  695.   if (TREE_CODE (binfo) == TREE_VEC)
  696.     type = BINFO_TYPE (binfo);
  697.   else if (TREE_CODE (binfo) == RECORD_TYPE)
  698.     {
  699.       type = binfo;
  700.       binfo = TYPE_BINFO (type);
  701.     }
  702.   else
  703.     my_friendly_abort (92);
  704.  
  705.   friends = current_class_type ? CLASSTYPE_FRIEND_CLASSES (type) : NULL_TREE;
  706.  
  707.   if (path_ptr)
  708.     {
  709.       basetype_path = TYPE_BINFO (type);
  710.       BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
  711.     }
  712.  
  713.   if (parent == type || parent == basetype_path)
  714.     {
  715.       /* If the distance is 0, then we don't really need
  716.      a path pointer, but we shouldn't let garbage go back.  */
  717.       if (path_ptr)
  718.     *path_ptr = basetype_path;
  719.       return 0;
  720.     }
  721.  
  722.   rval = get_base_distance_recursive (binfo, 0, 0, NULL_TREE, -1,
  723.                       &rval_private, &new_binfo, parent,
  724.                       path_ptr, protect, &via_virtual, 0);
  725.  
  726.   if (path_ptr)
  727.     BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE;
  728.  
  729.   basetype_path = binfo;
  730.  
  731.   dfs_walk (binfo, dfs_unmark, markedp);
  732.  
  733.   binfo = new_binfo;
  734.  
  735.   /* Visibilities don't count if we found an ambiguous basetype.  */
  736.   if (rval == -2)
  737.     rval_private = 0;
  738.  
  739.   if (rval && protect && rval_private)
  740.     return -3;
  741.  
  742.   if (path_ptr)
  743.     *path_ptr = binfo;
  744.   return rval;
  745. }
  746.  
  747. /* Search for a member with name NAME in a multiple inheritance lattice
  748.    specified by TYPE.  If it does not exist, return NULL_TREE.
  749.    If the member is ambiguously referenced, return `error_mark_node'.
  750.    Otherwise, return the FIELD_DECL.  */
  751.  
  752. /* Do a 1-level search for NAME as a member of TYPE.  The caller
  753.    must figure out whether it has a visible path to this field.
  754.    (Since it is only one level, this is reasonable.)  */
  755. static tree
  756. lookup_field_1 (type, name)
  757.      tree type, name;
  758. {
  759.   register tree field = TYPE_FIELDS (type);
  760.  
  761. #ifdef GATHER_STATISTICS
  762.   n_calls_lookup_field_1++;
  763. #endif
  764.   while (field)
  765.     {
  766. #ifdef GATHER_STATISTICS
  767.       n_fields_searched++;
  768. #endif
  769.       if (DECL_NAME (field) == NULL_TREE
  770.       && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)
  771.     {
  772.       tree temp = lookup_field_1 (TREE_TYPE (field), name);
  773.       if (temp)
  774.         return temp;
  775.     }
  776.       if (DECL_NAME (field) == name)
  777.     {
  778.       if ((TREE_CODE(field) == VAR_DECL || TREE_CODE(field) == CONST_DECL)
  779.           && DECL_ASSEMBLER_NAME (field) != NULL)
  780.         GNU_xref_ref(current_function_decl,
  781.              IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (field)));
  782.       return field;
  783.     }
  784.       field = TREE_CHAIN (field);
  785.     }
  786.   /* Not found.  */
  787.   if (name == _vptr_name)
  788.     {
  789.       /* Give the user what s/he thinks s/he wants.  */
  790.       if (TYPE_VIRTUAL_P (type))
  791.     return CLASSTYPE_VFIELD (type);
  792.     }
  793.   return NULL_TREE;
  794. }
  795.  
  796. /* Compute the visibility of FIELD.  This is done by computing
  797.    the visibility available to each type in BASETYPES (which comes
  798.    as a list of [via_public/basetype] in reverse order, namely base
  799.    class before derived class).  The first one which defines a
  800.    visibility defines the visibility for the field.  Otherwise, the
  801.    visibility of the field is that which occurs normally.
  802.  
  803.    Uses global variables CURRENT_CLASS_TYPE and
  804.    CURRENT_FUNCTION_DECL to use friend relationships
  805.    if necessary.
  806.  
  807.    This will be static when lookup_fnfield comes into this file.  */
  808.  
  809. #define PUBLIC_RETURN return (DECL_PUBLIC (field) = 1), visibility_public
  810. #define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), visibility_protected
  811. #define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), visibility_private
  812.  
  813. enum visibility_type
  814. compute_visibility (basetype_path, field)
  815.      tree basetype_path, field;
  816. {
  817.   enum visibility_type visibility = visibility_public;
  818.   tree types;
  819.   tree context = DECL_CLASS_CONTEXT (field);
  820.   /* Used once we go past an access gate that makes private really
  821.      deny us access from the context.  */
  822.   int really_private;
  823.  
  824.   if (context == NULL_TREE)
  825.     context = DECL_CONTEXT (field);
  826.  
  827.   /* Fields coming from nested anonymous unions have their DECL_CLASS_CONTEXT
  828.      slot set to the union type rather than the record type containing
  829.      the anonymous union.  In this case, DECL_FIELD_CONTEXT is correct.  */
  830.   if (context && TREE_CODE (context) == UNION_TYPE
  831.       && ANON_AGGRNAME_P (TYPE_IDENTIFIER (context)))
  832.     context = DECL_FIELD_CONTEXT (field);
  833.  
  834.   /* Virtual function tables are never private.  But we should know that
  835.      we are looking for this, and not even try to hide it.  */
  836.   if (DECL_NAME (field) && VFIELD_NAME_P (DECL_NAME (field)) == 1)
  837.     return visibility_public;
  838.  
  839.   /* Member function manipulating its own members.  */
  840.   if (current_class_type == context
  841.       || (context && current_class_type == TYPE_MAIN_VARIANT (context)))
  842.     PUBLIC_RETURN;
  843.  
  844.   /* Make these special cases fast.  */
  845.   if (BINFO_TYPE (basetype_path) == current_class_type)
  846.     {
  847.       if (DECL_PUBLIC (field))
  848.     return visibility_public;
  849.       if (DECL_PROTECTED (field))
  850.     return visibility_protected;
  851.       if (DECL_PRIVATE (field))
  852.     return visibility_private;
  853.     }
  854.  
  855.   /* Member found immediately within object.  */
  856.   if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE)
  857.     {
  858.       /* At the object's top level, public members are public.  */
  859.       if (!TREE_PROTECTED (field) && !TREE_PRIVATE (field))
  860.     PUBLIC_RETURN;
  861.  
  862.       /* Is it a friend function manipulating members that it gets by
  863.      virtue of its friendship?  Or are we friends with the class
  864.      that has FIELD?  */
  865.       if ((current_function_decl && is_friend (context, current_function_decl))
  866.       || (is_friend_type (context, current_class_type)))
  867.     PUBLIC_RETURN;
  868.  
  869.       if (current_class_type && DECL_VISIBILITY (field) == NULL_TREE)
  870.     {
  871.       /* If it's private, it's private, you letch.  */
  872.       if (TREE_PRIVATE (field))
  873.         PRIVATE_RETURN;
  874.  
  875.       /* ARM $11.5.  Member functions of a derived class can access the
  876.          non-static protected members of a base class only through a
  877.          pointer to the derived class, a reference to it, or an object
  878.          of it. Also any subsequently derived classes also have
  879.          access.  */
  880.       if (TREE_PROTECTED (field))
  881.         {
  882.           if (context == current_class_type
  883.           || UNIQUELY_DERIVED_FROM_P (context, current_class_type))
  884.         PUBLIC_RETURN;
  885.           else
  886.         PROTECTED_RETURN;
  887.         }
  888.       else
  889.         /* Will we ever actually reach here?  Doubt it.  */
  890.         my_friendly_abort (94);
  891.     }
  892.     }
  893.  
  894.   /* Is it a friend function manipulating members that it gets by
  895.      virtue of its friendship?  */
  896.   if (is_friend (context, current_function_decl))
  897.     PUBLIC_RETURN;
  898.  
  899.   /* must reverse more than one element */
  900.   basetype_path = reverse_path (basetype_path);
  901.   types = basetype_path;
  902.   really_private = 0;
  903.  
  904.   while (types)
  905.     {
  906.       tree member;
  907.       tree binfo = types;
  908.       tree type = BINFO_TYPE (binfo);
  909.  
  910.       member = purpose_member (type, DECL_VISIBILITY (field));
  911.       if (member)
  912.     {
  913.       visibility = (enum visibility_type)TREE_VALUE (member);
  914.       if (visibility == visibility_public
  915.           || is_friend (type, current_function_decl)
  916.           || (visibility == visibility_protected
  917.           && current_class_type
  918.           && UNIQUELY_DERIVED_FROM_P (context, current_class_type)))
  919.         visibility = visibility_public;
  920.       goto ret;
  921.     }
  922.  
  923.       /* Friends inherit the visibility of the class they inherit from.  */
  924.       if (is_friend (type, current_function_decl))
  925.     {
  926.       if (type == context)
  927.         {
  928.           visibility = visibility_public;
  929.           goto ret;
  930.         }
  931.       if (TREE_PROTECTED (field))
  932.         {
  933.           visibility = visibility_public;
  934.           goto ret;
  935.         }
  936.       /* else, may be a friend of a deeper base class */
  937.     }
  938.  
  939.       if (type == context)
  940.     break;
  941.  
  942.       types = BINFO_INHERITANCE_CHAIN (types);
  943.  
  944.       /* If the next type was not VIA_PUBLIC, then fields of all
  945.      remaining class past that one are private.  */
  946.       if (types)
  947.     {
  948.       if (TREE_VIA_PROTECTED (types))
  949.         {
  950.           if (really_private == 0)
  951.         really_private = 1;
  952.           else
  953.         visibility = visibility_protected;
  954.         }
  955.       else if (! TREE_VIA_PUBLIC (types))
  956.         {
  957.           if (really_private == 0)
  958.         really_private = 2;
  959.           else
  960.         visibility = visibility_private;
  961.         }
  962.     }
  963.     }
  964.  
  965.   /* No special visibilities apply.  Use normal rules.
  966.      No assignment needed for BASETYPEs here from the nreverse.
  967.      This is because we use it only for information about the
  968.      path to the base.  The code earlier dealt with what
  969.      happens when we are at the base level.  */
  970.  
  971.   if (visibility == visibility_public)
  972.     {
  973.       reverse_path (basetype_path);
  974.       if (TREE_PRIVATE (field))
  975.     PRIVATE_RETURN;
  976.       if (TREE_PROTECTED (field))
  977.     {
  978.       /* Used to check if the current class type was derived from
  979.          the type that contains the field.  This is wrong for
  980.          multiple inheritance because is gives one class reference
  981.          to protected members via another classes protected path.
  982.          I.e., if A; B1 : A; B2 : A;  Then B1 and B2 can access
  983.          their own members which are protected in A, but not
  984.          those same members in one another.  */
  985.       if (current_class_type
  986.           && UNIQUELY_DERIVED_FROM_P (context, current_class_type))
  987.         PUBLIC_RETURN;
  988.       PROTECTED_RETURN;
  989.     }
  990.       PUBLIC_RETURN;
  991.     }
  992.  
  993.   if (visibility == visibility_protected)
  994.     {
  995.       reverse_path (basetype_path);
  996.  
  997.       if (TREE_PRIVATE (field))
  998.     PRIVATE_RETURN;
  999.       /* We want to make sure that all non-private members in
  1000.      the current class (as derived) are accessible.  */
  1001.       if (current_class_type
  1002.       && UNIQUELY_DERIVED_FROM_P (context, current_class_type))
  1003.     PUBLIC_RETURN;
  1004.       PROTECTED_RETURN;
  1005.     }
  1006.  
  1007.   if (visibility == visibility_private && current_class_type != NULL_TREE)
  1008.     {
  1009.       reverse_path (basetype_path);
  1010.  
  1011.       /* If it's private in the base class, it stays private.  */
  1012.       if (TREE_PRIVATE (field))
  1013.     PRIVATE_RETURN;
  1014.  
  1015.       /* ARM $11.2: Specifying a base class private does not affect access
  1016.      to static members of the base class.  */
  1017.       if ((TREE_CODE (field) != FUNCTION_DECL
  1018.        && TREE_STATIC (field))
  1019.       || (TREE_CODE (field) == FUNCTION_DECL
  1020.           && DECL_STATIC_FUNCTION_P (field)))
  1021.     PUBLIC_RETURN;
  1022.  
  1023.       /* If it's public or protected in the base class, it becomes
  1024.      private in the derived class.  If we (the current_class_type)
  1025.      are not that immediately derived type that gets it as a
  1026.      private member, then the member is not visibile.  */
  1027.       if (immediately_derived (context, current_class_type))
  1028.     PUBLIC_RETURN;
  1029.  
  1030.       PRIVATE_RETURN;
  1031.     }
  1032.  
  1033.  ret:
  1034.   reverse_path (basetype_path);
  1035.  
  1036.   if (visibility == visibility_public)
  1037.     DECL_PUBLIC (field) = 1;
  1038.   else if (visibility == visibility_protected)
  1039.     DECL_PROTECTED (field) = 1;
  1040.   else if (visibility == visibility_private)
  1041.     DECL_PRIVATE (field) = 1;
  1042.   else my_friendly_abort (96);
  1043.   return visibility;
  1044. }
  1045.  
  1046. /* Routine to see if the sub-object denoted by the binfo PARENT can be
  1047.    found as a base class and sub-object of the object denoted by
  1048.    BINFO.  This routine relies upon binfos not being shared, except
  1049.    for binfos for virtual bases.  */
  1050. static int
  1051. is_subobject_of_p (parent, binfo)
  1052.      tree parent, binfo;
  1053. {
  1054.   tree binfos = BINFO_BASETYPES (binfo);
  1055.   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  1056.  
  1057.   if (parent == binfo)
  1058.     return 1;
  1059.  
  1060.   /* Process and/or queue base types.  */
  1061.   for (i = 0; i < n_baselinks; i++)
  1062.     {
  1063.       tree base_binfo = TREE_VEC_ELT (binfos, i);
  1064.       if (TREE_VIA_VIRTUAL (base_binfo))
  1065.     base_binfo = TYPE_BINFO (BINFO_TYPE (base_binfo));
  1066.       if (is_subobject_of_p (parent, base_binfo))
  1067.     return 1;
  1068.     }
  1069.   return 0;
  1070. }
  1071.  
  1072. /* See if a one FIELD_DECL hides another.  This routine is meant to
  1073.    correspond to ANSI working paper Sept 17, 1992 10p4.  The two
  1074.    binfos given are the binfos corresponding to the particular places
  1075.    the FIELD_DECLs are found.  This routine relies upon binfos not
  1076.    being shared, except for virtual bases. */
  1077. static int
  1078. hides (hider_binfo, hidee_binfo)
  1079.      tree hider_binfo, hidee_binfo;
  1080. {
  1081.   /* hider hides hidee, if hider has hidee as a base class and
  1082.      the instance of hidee is a sub-object of hider.  The first
  1083.      part is always true is the second part is true.
  1084.  
  1085.      When hider and hidee are the same (two ways to get to the exact
  1086.      same member) we consider either one as hiding the other. */
  1087.   return is_subobject_of_p (hidee_binfo, hider_binfo);
  1088. }
  1089.  
  1090. /* Very similar to lookup_fnfields_1 but it ensures that at least one
  1091.    function was declared inside the class given by TYPE.  It really should
  1092.    only return functions that match the given TYPE.  */
  1093. static int
  1094. lookup_fnfields_here (type, name)
  1095.      tree type, name;
  1096. {
  1097.   int index = lookup_fnfields_1 (type, name);
  1098.   tree fndecls;
  1099.  
  1100.   if (index <= 0)
  1101.     return index;
  1102.   fndecls = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
  1103.   while (fndecls)
  1104.     {
  1105.       if (TYPE_MAIN_VARIANT (DECL_CLASS_CONTEXT (fndecls))
  1106.       == TYPE_MAIN_VARIANT (type))
  1107.     return index;
  1108.       fndecls = TREE_CHAIN (fndecls);
  1109.     }
  1110.   return -1;
  1111. }
  1112.  
  1113. /* Look for a field named NAME in an inheritance lattice dominated by
  1114.    XBASETYPE.  PROTECT is zero if we can avoid computing visibility
  1115.    information, otherwise it is 1.  WANT_TYPE is 1 when we should only
  1116.    return TYPE_DECLs, if no TYPE_DECL can be found return NULL_TREE.
  1117.  
  1118.    It was not clear what should happen if WANT_TYPE is set, and an
  1119.    ambiguity is found.  At least one use (lookup_name) to not see
  1120.    the error.  */
  1121. tree
  1122. lookup_field (xbasetype, name, protect, want_type)
  1123.      register tree xbasetype, name;
  1124.      int protect, want_type;
  1125. {
  1126.   int head = 0, tail = 0;
  1127.   tree rval, rval_binfo = NULL_TREE, rval_binfo_h;
  1128.   tree type, basetype_chain, basetype_path;
  1129.   enum visibility_type this_v = visibility_default;
  1130.   tree entry, binfo, binfo_h;
  1131.   enum visibility_type own_visibility = visibility_default;
  1132.   int vbase_name_p = VBASE_NAME_P (name);
  1133.  
  1134.   /* rval_binfo is the binfo associated with the found member, note,
  1135.      this can be set with useful information, even when rval is not
  1136.      set, because it must deal with ALL members, not just non-function
  1137.      members.  It is used for ambiguity checking and the hidden
  1138.      checks.  Whereas rval is only set if a proper (not hidden)
  1139.      non-function member is found.  */
  1140.  
  1141.   /* rval_binfo_h and binfo_h are binfo values used when we perform the
  1142.      hiding checks, as virtual base classes may not be shared.  The strategy
  1143.      is we always go into the the binfo hierarchy owned by TYPE_BINFO of
  1144.      virtual base classes, as we cross virtual base class lines.  This way
  1145.      we know that binfo of a virtual base class will always == itself when
  1146.      found along any line.  (mrs)  */
  1147.  
  1148.   /* Things for memoization.  */
  1149.   char *errstr = 0;
  1150.  
  1151.   /* Set this to nonzero if we don't know how to compute
  1152.      accurate error messages for visibility.  */
  1153.   int index = MEMOIZED_HASH_FN (name);
  1154.  
  1155.   /* If we are looking for a constructor in a templated type, use the
  1156.      unspecialized name, as that is how we store it.  */
  1157.   if (IDENTIFIER_TEMPLATE (name))
  1158.     name = constructor_name (name);
  1159.  
  1160.   if (TREE_CODE (xbasetype) == TREE_VEC)
  1161.     basetype_path = xbasetype, type = BINFO_TYPE (xbasetype);
  1162.   else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)))
  1163.     basetype_path = TYPE_BINFO (xbasetype), type = xbasetype;
  1164.   else my_friendly_abort (97);
  1165.  
  1166.   if (CLASSTYPE_MTABLE_ENTRY (type))
  1167.     {
  1168.       tree tem = MEMOIZED_FIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);
  1169.  
  1170.       while (tem && TREE_PURPOSE (tem) != name)
  1171.     {
  1172.       memoized_fields_searched[0]++;
  1173.       tem = TREE_CHAIN (tem);
  1174.     }
  1175.       if (tem)
  1176.     {
  1177.       if (protect && TREE_TYPE (tem))
  1178.         {
  1179.           error (TREE_STRING_POINTER (TREE_TYPE (tem)),
  1180.              IDENTIFIER_POINTER (name),
  1181.              TYPE_NAME_STRING (DECL_FIELD_CONTEXT (TREE_VALUE (tem))));
  1182.           return error_mark_node;
  1183.         }
  1184.       if (TREE_VALUE (tem) == NULL_TREE)
  1185.         memoized_fast_rejects[0] += 1;
  1186.       else
  1187.         memoized_fast_finds[0] += 1;
  1188.       return TREE_VALUE (tem);
  1189.     }
  1190.     }
  1191.  
  1192. #ifdef GATHER_STATISTICS
  1193.   n_calls_lookup_field++;
  1194. #endif
  1195.   if (protect && flag_memoize_lookups && ! global_bindings_p ())
  1196.     entry = make_memoized_table_entry (type, name, 0);
  1197.   else
  1198.     entry = 0;
  1199.  
  1200.   rval = lookup_field_1 (type, name);
  1201.   if (rval || lookup_fnfields_here (type, name)>=0)
  1202.     {
  1203.       rval_binfo = basetype_path;
  1204.       rval_binfo_h = rval_binfo;
  1205.     }
  1206.  
  1207.   if (rval && TREE_CODE (rval) != TYPE_DECL && want_type)
  1208.     rval = NULL_TREE;
  1209.  
  1210.   if (rval)
  1211.     {
  1212.       if (protect)
  1213.     {
  1214.       if (TREE_PRIVATE (rval) | TREE_PROTECTED (rval))
  1215.         this_v = compute_visibility (basetype_path, rval);
  1216.       if (TREE_CODE (rval) == CONST_DECL)
  1217.         {
  1218.           if (this_v == visibility_private)
  1219.         errstr = "enum `%s' is a private value of class `%s'";
  1220.           else if (this_v == visibility_protected)
  1221.         errstr = "enum `%s' is a protected value of class `%s'";
  1222.         }
  1223.       else
  1224.         {
  1225.           if (this_v == visibility_private)
  1226.         errstr = "member `%s' is a private member of class `%s'";
  1227.           else if (this_v == visibility_protected)
  1228.         errstr = "member `%s' is a protected member of class `%s'";
  1229.         }
  1230.     }
  1231.  
  1232.       if (entry)
  1233.     {
  1234.       if (errstr)
  1235.         {
  1236.           /* This depends on behavior of lookup_field_1!  */
  1237.           tree error_string = my_build_string (errstr);
  1238.           TREE_TYPE (entry) = error_string;
  1239.         }
  1240.       else
  1241.         {
  1242.           /* Let entry know there is no problem with this access.  */
  1243.           TREE_TYPE (entry) = NULL_TREE;
  1244.         }
  1245.       TREE_VALUE (entry) = rval;
  1246.     }
  1247.  
  1248.       if (errstr && protect)
  1249.     {
  1250.       error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));
  1251.       return error_mark_node;
  1252.     }
  1253.       return rval;
  1254.     }
  1255.  
  1256.   basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);
  1257.   TREE_VIA_PUBLIC (basetype_chain) = 1;
  1258.  
  1259.   /* The ambiguity check relies upon breadth first searching. */
  1260.  
  1261.   search_stack = push_search_level (search_stack, &search_obstack);
  1262.   BINFO_VIA_PUBLIC (basetype_path) = 1;
  1263.   BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
  1264.   binfo = basetype_path;
  1265.   binfo_h = binfo;
  1266.  
  1267.   while (1)
  1268.     {
  1269.       tree binfos = BINFO_BASETYPES (binfo);
  1270.       int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  1271.       tree nval;
  1272.  
  1273.       /* Process and/or queue base types.  */
  1274.       for (i = 0; i < n_baselinks; i++)
  1275.     {
  1276.       tree base_binfo = TREE_VEC_ELT (binfos, i);
  1277.       if (BINFO_FIELDS_MARKED (base_binfo) == 0)
  1278.         {
  1279.           tree btypes;
  1280.  
  1281.           SET_BINFO_FIELDS_MARKED (base_binfo);
  1282.           btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain);
  1283.           TREE_VIA_PUBLIC (btypes) = TREE_VIA_PUBLIC (base_binfo);
  1284.           TREE_VIA_PROTECTED (btypes) = TREE_VIA_PROTECTED (base_binfo);
  1285.           TREE_VIA_VIRTUAL (btypes) = TREE_VIA_VIRTUAL (base_binfo);
  1286.           if (TREE_VIA_VIRTUAL (base_binfo))
  1287.         btypes = tree_cons (NULL_TREE,
  1288.                     TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))),
  1289.                     btypes);
  1290.           else
  1291.         btypes = tree_cons (NULL_TREE,
  1292.                     TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i),
  1293.                     btypes);
  1294.           obstack_ptr_grow (&search_obstack, btypes);
  1295.           tail += 1;
  1296.           if (tail >= search_stack->limit)
  1297.         my_friendly_abort (98);
  1298.         }
  1299.     }
  1300.  
  1301.       /* Process head of queue, if one exists.  */
  1302.       if (head >= tail)
  1303.     break;
  1304.  
  1305.       basetype_chain = search_stack->first[head++];
  1306.       binfo_h = TREE_VALUE (basetype_chain);
  1307.       basetype_chain = TREE_CHAIN (basetype_chain);
  1308.       basetype_path = TREE_VALUE (basetype_chain);
  1309.       if (TREE_CHAIN (basetype_chain))
  1310.     BINFO_INHERITANCE_CHAIN (basetype_path) = TREE_VALUE (TREE_CHAIN (basetype_chain));
  1311.       else
  1312.     BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
  1313.  
  1314.       binfo = basetype_path;
  1315.       type = BINFO_TYPE (binfo);
  1316.  
  1317.       /* See if we can find NAME in TYPE.  If RVAL is nonzero,
  1318.      and we do find NAME in TYPE, verify that such a second
  1319.      sighting is in fact legal.  */
  1320.  
  1321.       nval = lookup_field_1 (type, name);
  1322.  
  1323.       if (nval || lookup_fnfields_here (type, name)>=0)
  1324.     {
  1325.       if (rval_binfo && hides (rval_binfo_h, binfo_h))
  1326.         {
  1327.           /* This is ok, the member found is in rval_binfo, not
  1328.          here (binfo). */
  1329.         }
  1330.       else if (rval_binfo==NULL_TREE || hides (binfo_h, rval_binfo_h))
  1331.         {
  1332.           /* This is ok, the member found is here (binfo), not in
  1333.          rval_binfo. */
  1334.           if (nval)
  1335.         {
  1336.           rval = nval;
  1337.           if (entry || protect)
  1338.             this_v = compute_visibility (basetype_path, rval);
  1339.           /* These may look ambiguous, but they really are not.  */
  1340.           if (vbase_name_p)
  1341.             break;
  1342.         }
  1343.           else
  1344.         {
  1345.           /* Undo finding it before, as something else hides it. */
  1346.           rval = NULL_TREE;
  1347.         }
  1348.           rval_binfo = binfo;
  1349.           rval_binfo_h = binfo_h;
  1350.         }
  1351.       else
  1352.         {
  1353.           /* This is ambiguous. */
  1354.           errstr = "request for member `%s' is ambiguous";
  1355.           protect = 2;
  1356.           break;
  1357.         }
  1358.     }
  1359.     }
  1360.   {
  1361.     tree *tp = search_stack->first;
  1362.     tree *search_tail = tp + tail;
  1363.  
  1364.     if (entry)
  1365.       TREE_VALUE (entry) = rval;
  1366.  
  1367.     if (want_type && (rval == NULL_TREE || TREE_CODE (rval) != TYPE_DECL))
  1368.       {
  1369.     rval = NULL_TREE;
  1370.     errstr = 0;
  1371.       }
  1372.  
  1373.     /* If this FIELD_DECL defines its own visibility, deal with that.  */
  1374.     if (rval && errstr == 0
  1375.     && ((protect&1) || entry)
  1376.     && DECL_LANG_SPECIFIC (rval)
  1377.     && DECL_VISIBILITY (rval))
  1378.       {
  1379.     while (tp < search_tail)
  1380.       {
  1381.         /* If is possible for one of the derived types on the
  1382.            path to have defined special visibility for this
  1383.            field.  Look for such declarations and report an
  1384.            error if a conflict is found.  */
  1385.         enum visibility_type new_v;
  1386.  
  1387.         if (this_v != visibility_default)
  1388.           new_v = compute_visibility (TREE_VALUE (TREE_CHAIN (*tp)), rval);
  1389.         if (this_v != visibility_default && new_v != this_v)
  1390.           {
  1391.         errstr = "conflicting visibilities to member `%s'";
  1392.         this_v = visibility_default;
  1393.           }
  1394.         own_visibility = new_v;
  1395.         CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
  1396.         tp += 1;
  1397.       }
  1398.       }
  1399.     else
  1400.       {
  1401.     while (tp < search_tail)
  1402.       {
  1403.         CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
  1404.         tp += 1;
  1405.       }
  1406.       }
  1407.   }
  1408.   search_stack = pop_search_level (search_stack);
  1409.  
  1410.   if (errstr == 0)
  1411.     {
  1412.       if (own_visibility == visibility_private)
  1413.     errstr = "member `%s' declared private";
  1414.       else if (own_visibility == visibility_protected)
  1415.     errstr = "member `%s' declared protected";
  1416.       else if (this_v == visibility_private)
  1417.     errstr = TREE_PRIVATE (rval)
  1418.       ? "member `%s' is private"
  1419.         : "member `%s' is from private base class";
  1420.       else if (this_v == visibility_protected)
  1421.     errstr = TREE_PROTECTED (rval)
  1422.       ? "member `%s' is protected"
  1423.         : "member `%s' is from protected base class";
  1424.     }
  1425.  
  1426.   if (entry)
  1427.     {
  1428.       if (errstr)
  1429.     {
  1430.       tree error_string = my_build_string (errstr);
  1431.       /* Save error message with entry.  */
  1432.       TREE_TYPE (entry) = error_string;
  1433.     }
  1434.       else
  1435.     {
  1436.       /* Mark entry as having no error string.  */
  1437.       TREE_TYPE (entry) = NULL_TREE;
  1438.     }
  1439.     }
  1440.  
  1441.   if (errstr && protect)
  1442.     {
  1443.       char *p = IDENTIFIER_POINTER (name), *q = NULL;
  1444.       if (IDENTIFIER_OPNAME_P (name))
  1445.     {
  1446.       q = operator_name_string (name);
  1447.       p = (char *) xmalloc (9 + strlen (q) + 1);
  1448.       sprintf (p, "operator %s", q);
  1449.     }
  1450.  
  1451.       error (errstr, p, TYPE_NAME_STRING (type));
  1452.       if (q)
  1453.     free (p);
  1454.       rval = error_mark_node;
  1455.     }
  1456.   return rval;
  1457. }
  1458.  
  1459. /* Try to find NAME inside a nested class.  */
  1460. tree
  1461. lookup_nested_field (name, complain)
  1462.      tree name;
  1463.      int complain;
  1464. {
  1465.   register tree t;
  1466.  
  1467.   tree id = NULL_TREE;
  1468.   if (TREE_CHAIN (current_class_type))
  1469.     {
  1470.       /* Climb our way up the nested ladder, seeing if we're trying to
  1471.      modify a field in an enclosing class.  If so, we should only
  1472.      be able to modify if it's static.  */
  1473.       for (t = TREE_CHAIN (current_class_type);
  1474.        t && DECL_CONTEXT (t);
  1475.        t = TREE_CHAIN (DECL_CONTEXT (t)))
  1476.     {
  1477.       if (TREE_CODE (DECL_CONTEXT (t)) != RECORD_TYPE)
  1478.         break;
  1479.  
  1480.       /* N.B.: lookup_field will do the visibility checking for us */
  1481.       id = lookup_field (DECL_CONTEXT (t), name, complain, 0);
  1482.       if (id == error_mark_node)
  1483.         {
  1484.           id = NULL_TREE;
  1485.           continue;
  1486.         }
  1487.  
  1488.       if (id != NULL_TREE)
  1489.         {
  1490.           if (TREE_CODE (id) == FIELD_DECL
  1491.           && ! TREE_STATIC (id)
  1492.           && TREE_TYPE (id) != error_mark_node)
  1493.         {
  1494.           if (complain)
  1495.             {
  1496.               /* At parse time, we don't want to give this error, since
  1497.              we won't have enough state to make this kind of
  1498.              decision properly.  But there are times (e.g., with
  1499.              enums in nested classes) when we do need to call
  1500.              this fn at parse time.  So, in those cases, we pass
  1501.              complain as a 0 and just return a NULL_TREE.  */
  1502.               error ("assignment to non-static member `%s' of enclosing class `%s'",
  1503.                  lang_printable_name (id),
  1504.                  IDENTIFIER_POINTER (TYPE_IDENTIFIER
  1505.                          (DECL_CONTEXT (t))));
  1506.               /* Mark this for do_identifier().  It would otherwise
  1507.              claim that the variable was undeclared.  */
  1508.               TREE_TYPE (id) = error_mark_node;
  1509.             }
  1510.           else
  1511.             {
  1512.               id = NULL_TREE;
  1513.               continue;
  1514.             }
  1515.         }
  1516.           break;
  1517.         }
  1518.     }
  1519.     }
  1520.  
  1521.   return id;
  1522. }
  1523.  
  1524. /* TYPE is a class type. Return the index of the fields within
  1525.    the method vector with name NAME, or -1 is no such field exists.  */
  1526. static int
  1527. lookup_fnfields_1 (type, name)
  1528.      tree type, name;
  1529. {
  1530.   register tree method_vec = CLASSTYPE_METHOD_VEC (type);
  1531.  
  1532.   if (method_vec != 0)
  1533.     {
  1534.       register tree *methods = &TREE_VEC_ELT (method_vec, 0);
  1535.       register tree *end = TREE_VEC_END (method_vec);
  1536.  
  1537. #ifdef GATHER_STATISTICS
  1538.       n_calls_lookup_fnfields_1++;
  1539. #endif
  1540.       if (*methods && name == constructor_name (type))
  1541.     return 0;
  1542.  
  1543.       while (++methods != end)
  1544.     {
  1545. #ifdef GATHER_STATISTICS
  1546.       n_outer_fields_searched++;
  1547. #endif
  1548.       if (DECL_NAME (*methods) == name)
  1549.         break;
  1550.     }
  1551.       if (methods != end)
  1552.     return methods - &TREE_VEC_ELT (method_vec, 0);
  1553.     }
  1554.  
  1555.   return -1;
  1556. }
  1557.  
  1558. /* Starting from BASETYPE, return a TREE_BASELINK-like object
  1559.    which gives the following information (in a list):
  1560.  
  1561.    TREE_TYPE: list of basetypes needed to get to...
  1562.    TREE_VALUE: list of all functions in of given type
  1563.    which have name NAME.
  1564.  
  1565.    No visibility information is computed by this function,
  1566.    other then to adorn the list of basetypes with
  1567.    TREE_VIA_PUBLIC.
  1568.  
  1569.    If there are two ways to find a name (two members), if COMPLAIN is
  1570.    non-zero, then error_mark_node is returned, and an error message is
  1571.    printed, otherwise, just an error_mark_node is returned.
  1572.  
  1573.    As a special case, is COMPLAIN is -1, we don't complain, and we
  1574.    don't return error_mark_node, but rather the complete list of
  1575.    virtuals.  This is used by get_virtuals_named_this.  */
  1576. tree
  1577. lookup_fnfields (basetype_path, name, complain)
  1578.      tree basetype_path, name;
  1579.      int complain;
  1580. {
  1581.   int head = 0, tail = 0;
  1582.   tree type, rval, rval_binfo = NULL_TREE, rvals = NULL_TREE, rval_binfo_h;
  1583.   tree entry, binfo, basetype_chain, binfo_h;
  1584.   int find_all = 0;
  1585.  
  1586.   /* rval_binfo is the binfo associated with the found member, note,
  1587.      this can be set with useful information, even when rval is not
  1588.      set, because it must deal with ALL members, not just function
  1589.      members.  It is used for ambiguity checking and the hidden
  1590.      checks.  Whereas rval is only set if a proper (not hidden)
  1591.      function member is found.  */
  1592.  
  1593.   /* rval_binfo_h and binfo_h are binfo values used when we perform the
  1594.      hiding checks, as virtual base classes may not be shared.  The strategy
  1595.      is we always go into the the binfo hierarchy owned by TYPE_BINFO of
  1596.      virtual base classes, as we cross virtual base class lines.  This way
  1597.      we know that binfo of a virtual base class will always == itself when
  1598.      found along any line.  (mrs)  */
  1599.  
  1600.   /* For now, don't try this.  */
  1601.   int protect = complain;
  1602.  
  1603.   /* Things for memoization.  */
  1604.   char *errstr = 0;
  1605.  
  1606.   /* Set this to nonzero if we don't know how to compute
  1607.      accurate error messages for visibility.  */
  1608.   int index = MEMOIZED_HASH_FN (name);
  1609.  
  1610.   if (complain == -1)
  1611.     {
  1612.       find_all = 1;
  1613.       protect = complain = 0;
  1614.     }
  1615.  
  1616.   /* If we are looking for a constructor in a templated type, use the
  1617.      unspecialized name, as that is how we store it.  */
  1618.   if (IDENTIFIER_TEMPLATE (name))
  1619.     name = constructor_name (name);
  1620.  
  1621.   binfo = basetype_path;
  1622.   binfo_h = binfo;
  1623.   type = BINFO_TYPE (basetype_path);
  1624.  
  1625.   /* The memoization code is in need of maintenance. */
  1626.   if (!find_all && CLASSTYPE_MTABLE_ENTRY (type))
  1627.     {
  1628.       tree tem = MEMOIZED_FNFIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);
  1629.  
  1630.       while (tem && TREE_PURPOSE (tem) != name)
  1631.     {
  1632.       memoized_fields_searched[1]++;
  1633.       tem = TREE_CHAIN (tem);
  1634.     }
  1635.       if (tem)
  1636.     {
  1637.       if (protect && TREE_TYPE (tem))
  1638.         {
  1639.           error (TREE_STRING_POINTER (TREE_TYPE (tem)),
  1640.              IDENTIFIER_POINTER (name),
  1641.              TYPE_NAME_STRING (DECL_CLASS_CONTEXT (TREE_VALUE (TREE_VALUE (tem)))));
  1642.           return error_mark_node;
  1643.         }
  1644.       if (TREE_VALUE (tem) == NULL_TREE)
  1645.         {
  1646.           memoized_fast_rejects[1] += 1;
  1647.           return NULL_TREE;
  1648.         }
  1649.       else
  1650.         {
  1651.           /* Want to return this, but we must make sure
  1652.          that visibility information is consistent.  */
  1653.           tree baselink = TREE_VALUE (tem);
  1654.           tree memoized_basetypes = TREE_PURPOSE (baselink);
  1655.           tree these_basetypes = basetype_path;
  1656.           while (memoized_basetypes && these_basetypes)
  1657.         {
  1658.           memoized_fields_searched[1]++;
  1659.           if (TREE_VALUE (memoized_basetypes) != these_basetypes)
  1660.             break;
  1661.           memoized_basetypes = TREE_CHAIN (memoized_basetypes);
  1662.           these_basetypes = BINFO_INHERITANCE_CHAIN (these_basetypes);
  1663.         }
  1664.           /* The following statement is true only when both are NULL.  */
  1665.           if (memoized_basetypes == these_basetypes)
  1666.         {
  1667.           memoized_fast_finds[1] += 1;
  1668.           return TREE_VALUE (tem);
  1669.         }
  1670.           /* else, we must re-find this field by hand.  */
  1671.           baselink = tree_cons (basetype_path, TREE_VALUE (baselink), TREE_CHAIN (baselink));
  1672.           return baselink;
  1673.         }
  1674.     }
  1675.     }
  1676.  
  1677. #ifdef GATHER_STATISTICS
  1678.   n_calls_lookup_fnfields++;
  1679. #endif
  1680.   if (protect && flag_memoize_lookups && ! global_bindings_p ())
  1681.     entry = make_memoized_table_entry (type, name, 1);
  1682.   else
  1683.     entry = 0;
  1684.  
  1685.   index = lookup_fnfields_here (type, name);
  1686.   if (index >= 0 || lookup_field_1 (type, name))
  1687.     {
  1688.       rval_binfo = basetype_path;
  1689.       rval_binfo_h = rval_binfo;
  1690.     }
  1691.  
  1692.   if (index >= 0)
  1693.     {
  1694.       rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
  1695.       rvals = my_tree_cons (basetype_path, rval, rvals);
  1696.       if (BINFO_BASETYPES (binfo) && CLASSTYPE_BASELINK_VEC (type))
  1697.     TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);
  1698.  
  1699.       if (entry)
  1700.     {
  1701.       TREE_VALUE (entry) = rvals;
  1702.       TREE_TYPE (entry) = NULL_TREE;
  1703.     }
  1704.  
  1705.       if (errstr && protect)
  1706.     {
  1707.       error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));
  1708.       return error_mark_node;
  1709.     }
  1710.       return rvals;
  1711.     }
  1712.   rval = NULL_TREE;
  1713.  
  1714.   basetype_chain = CLASSTYPE_BINFO_AS_LIST (type);
  1715.   TREE_VIA_PUBLIC (basetype_chain) = 1;
  1716.  
  1717.   /* The ambiguity check relies upon breadth first searching. */
  1718.  
  1719.   search_stack = push_search_level (search_stack, &search_obstack);
  1720.   BINFO_VIA_PUBLIC (basetype_path) = 1;
  1721.   BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
  1722.   binfo = basetype_path;
  1723.   binfo_h = binfo;
  1724.  
  1725.   while (1)
  1726.     {
  1727.       tree binfos = BINFO_BASETYPES (binfo);
  1728.       int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  1729.       int index;
  1730.  
  1731.       /* Process and/or queue base types.  */
  1732.       for (i = 0; i < n_baselinks; i++)
  1733.     {
  1734.       tree base_binfo = TREE_VEC_ELT (binfos, i);
  1735.       if (BINFO_FIELDS_MARKED (base_binfo) == 0)
  1736.         {
  1737.           tree btypes;
  1738.  
  1739.           SET_BINFO_FIELDS_MARKED (base_binfo);
  1740.           btypes = my_tree_cons (NULL_TREE, base_binfo, basetype_chain);
  1741.           TREE_VIA_PUBLIC (btypes) = TREE_VIA_PUBLIC (base_binfo);
  1742.           TREE_VIA_PROTECTED (btypes) = TREE_VIA_PROTECTED (base_binfo);
  1743.           TREE_VIA_VIRTUAL (btypes) = TREE_VIA_VIRTUAL (base_binfo);
  1744.           if (TREE_VIA_VIRTUAL (base_binfo))
  1745.         btypes = tree_cons (NULL_TREE,
  1746.                     TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))),
  1747.                     btypes);
  1748.           else
  1749.         btypes = tree_cons (NULL_TREE,
  1750.                     TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i),
  1751.                     btypes);
  1752.           obstack_ptr_grow (&search_obstack, btypes);
  1753.           tail += 1;
  1754.           if (tail >= search_stack->limit)
  1755.         my_friendly_abort (99);
  1756.         }
  1757.     }
  1758.  
  1759.       /* Process head of queue, if one exists.  */
  1760.       if (head >= tail)
  1761.     break;
  1762.  
  1763.       basetype_chain = search_stack->first[head++];
  1764.       binfo_h = TREE_VALUE (basetype_chain);
  1765.       basetype_chain = TREE_CHAIN (basetype_chain);
  1766.       basetype_path = TREE_VALUE (basetype_chain);
  1767.       if (TREE_CHAIN (basetype_chain))
  1768.     BINFO_INHERITANCE_CHAIN (basetype_path) = TREE_VALUE (TREE_CHAIN (basetype_chain));
  1769.       else
  1770.     BINFO_INHERITANCE_CHAIN (basetype_path) = NULL_TREE;
  1771.  
  1772.       binfo = basetype_path;
  1773.       type = BINFO_TYPE (binfo);
  1774.  
  1775.       /* See if we can find NAME in TYPE.  If RVAL is nonzero,
  1776.      and we do find NAME in TYPE, verify that such a second
  1777.      sighting is in fact legal.  */
  1778.  
  1779.       index = lookup_fnfields_here (type, name);
  1780.  
  1781.       if (index >= 0 || (lookup_field_1 (type, name)!=NULL_TREE && !find_all))
  1782.     {
  1783.       if (rval_binfo && !find_all && hides (rval_binfo_h, binfo_h))
  1784.         {
  1785.           /* This is ok, the member found is in rval_binfo, not
  1786.          here (binfo). */
  1787.         }
  1788.       else if (rval_binfo==NULL_TREE || find_all || hides (binfo_h, rval_binfo_h))
  1789.         {
  1790.           /* This is ok, the member found is here (binfo), not in
  1791.          rval_binfo. */
  1792.           if (index >= 0)
  1793.         {
  1794.           rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
  1795.           /* Note, rvals can only be previously set if find_all is
  1796.              true.  */
  1797.           rvals = my_tree_cons (basetype_path, rval, rvals);
  1798.           if (TYPE_BINFO_BASETYPES (type)
  1799.               && CLASSTYPE_BASELINK_VEC (type))
  1800.             TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);
  1801.         }
  1802.           else
  1803.         {
  1804.           /* Undo finding it before, as something else hides it. */
  1805.           rval = NULL_TREE;
  1806.           rvals = NULL_TREE;
  1807.         }
  1808.           rval_binfo = binfo;
  1809.           rval_binfo_h = binfo_h;
  1810.         }
  1811.       else
  1812.         {
  1813.           /* This is ambiguous. */
  1814.           errstr = "request for member `%s' is ambiguous";
  1815.           rvals = error_mark_node;
  1816.           break;
  1817.         }
  1818.     }
  1819.     }
  1820.   {
  1821.     tree *tp = search_stack->first;
  1822.     tree *search_tail = tp + tail;
  1823.  
  1824.     while (tp < search_tail)
  1825.       {
  1826.     CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp)));
  1827.     tp += 1;
  1828.       }
  1829.   }
  1830.   search_stack = pop_search_level (search_stack);
  1831.  
  1832.   if (entry)
  1833.     {
  1834.       if (errstr)
  1835.     {
  1836.       tree error_string = my_build_string (errstr);
  1837.       /* Save error message with entry.  */
  1838.       TREE_TYPE (entry) = error_string;
  1839.     }
  1840.       else
  1841.     {
  1842.       /* Mark entry as having no error string.  */
  1843.       TREE_TYPE (entry) = NULL_TREE;
  1844.       TREE_VALUE (entry) = rvals;
  1845.     }
  1846.     }
  1847.  
  1848.   if (errstr && protect)
  1849.     {
  1850.       error (errstr, IDENTIFIER_POINTER (name), TYPE_NAME_STRING (type));
  1851.       rvals = error_mark_node;
  1852.     }
  1853.  
  1854.   return rvals;
  1855. }
  1856.  
  1857. /* BREADTH-FIRST SEARCH ROUTINES.  */
  1858.  
  1859. /* Search a multiple inheritance hierarchy by breadth-first search.
  1860.  
  1861.    TYPE is an aggregate type, possibly in a multiple-inheritance hierarchy.
  1862.    TESTFN is a function, which, if true, means that our condition has been met,
  1863.    and its return value should be returned.
  1864.    QFN, if non-NULL, is a predicate dictating whether the type should
  1865.    even be queued.  */
  1866.  
  1867. HOST_WIDE_INT
  1868. breadth_first_search (binfo, testfn, qfn)
  1869.      tree binfo;
  1870.      int (*testfn)();
  1871.      int (*qfn)();
  1872. {
  1873.   int head = 0, tail = 0;
  1874.   int rval = 0;
  1875.  
  1876.   search_stack = push_search_level (search_stack, &search_obstack);
  1877.  
  1878.   while (1)
  1879.     {
  1880.       tree binfos = BINFO_BASETYPES (binfo);
  1881.       int n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  1882.       int i;
  1883.  
  1884.       /* Process and/or queue base types.  */
  1885.       for (i = 0; i < n_baselinks; i++)
  1886.     {
  1887.       tree base_binfo = TREE_VEC_ELT (binfos, i);
  1888.  
  1889.       if (BINFO_MARKED (base_binfo) == 0
  1890.           && (qfn == 0 || (*qfn) (binfo, i)))
  1891.         {
  1892.           SET_BINFO_MARKED (base_binfo);
  1893.           obstack_ptr_grow (&search_obstack, binfo);
  1894.           obstack_ptr_grow (&search_obstack, (HOST_WIDE_INT) i);
  1895.           tail += 2;
  1896.           if (tail >= search_stack->limit)
  1897.         my_friendly_abort (100);
  1898.         }
  1899.     }
  1900.       /* Process head of queue, if one exists.  */
  1901.       if (head >= tail)
  1902.     {
  1903.       rval = 0;
  1904.       break;
  1905.     }
  1906.  
  1907.       binfo = search_stack->first[head++];
  1908.       i = (HOST_WIDE_INT) search_stack->first[head++];
  1909.       if (rval = (*testfn) (binfo, i))
  1910.     break;
  1911.       binfo = BINFO_BASETYPE (binfo, i);
  1912.     }
  1913.   {
  1914.     tree *tp = search_stack->first;
  1915.     tree *search_tail = tp + tail;
  1916.     while (tp < search_tail)
  1917.       {
  1918.     tree binfo = *tp++;
  1919.     int i = (HOST_WIDE_INT)(*tp++);
  1920.     CLEAR_BINFO_MARKED (BINFO_BASETYPE (binfo, i));
  1921.       }
  1922.   }
  1923.  
  1924.   search_stack = pop_search_level (search_stack);
  1925.   return rval;
  1926. }
  1927.  
  1928. /* Functions to use in breadth first searches.  */
  1929. typedef tree (*pft)();
  1930. typedef int (*pfi)();
  1931.  
  1932. int tree_needs_constructor_p (binfo, i)
  1933.      tree binfo;
  1934.      int i;
  1935. {
  1936.   tree basetype;
  1937.   my_friendly_assert (i != 0, 296);
  1938.   basetype = BINFO_TYPE (BINFO_BASETYPE (binfo, i));
  1939.   return TYPE_NEEDS_CONSTRUCTOR (basetype);
  1940. }
  1941.  
  1942. static tree declarator;
  1943.  
  1944. static tree
  1945. get_virtuals_named_this (binfo)
  1946.      tree binfo;
  1947. {
  1948.   tree fields;
  1949.  
  1950.   fields = lookup_fnfields (binfo, declarator, -1);
  1951.   /* fields cannot be error_mark_node */
  1952.  
  1953.   if (fields == 0)
  1954.     return 0;
  1955.  
  1956.   /* Get to the function decls, and return the first virtual function
  1957.      with this name, if there is one.  */
  1958.   while (fields)
  1959.     {
  1960.       tree fndecl;
  1961.  
  1962.       for (fndecl = TREE_VALUE (fields); fndecl; fndecl = DECL_CHAIN (fndecl))
  1963.     if (DECL_VINDEX (fndecl))
  1964.       return fields;
  1965.       fields = next_baselink (fields);
  1966.     }
  1967.   return NULL_TREE;
  1968. }
  1969.  
  1970. static tree get_virtual_destructor (binfo, i)
  1971.      tree binfo;
  1972.      int i;
  1973. {
  1974.   tree type = BINFO_TYPE (binfo);
  1975.   if (i >= 0)
  1976.     type = BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), i));
  1977.   if (TYPE_HAS_DESTRUCTOR (type)
  1978.       && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0)))
  1979.     return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 0);
  1980.   return 0;
  1981. }
  1982.  
  1983. int tree_has_any_destructor_p (binfo, i)
  1984.      tree binfo;
  1985.      int i;
  1986. {
  1987.   tree type = BINFO_TYPE (binfo);
  1988.   if (i >= 0)
  1989.     type = BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo), i));
  1990.   return TYPE_NEEDS_DESTRUCTOR (type);
  1991. }
  1992.  
  1993. /* Given a class type TYPE, and a function decl FNDECL,
  1994.    look for the first function the TYPE's hierarchy which
  1995.    FNDECL could match as a virtual function.
  1996.  
  1997.    DTORP is nonzero if we are looking for a destructor.  Destructors
  1998.    need special treatment because they do not match by name.  */
  1999. tree
  2000. get_first_matching_virtual (binfo, fndecl, dtorp)
  2001.      tree binfo, fndecl;
  2002.      int dtorp;
  2003. {
  2004.   tree tmp = NULL_TREE;
  2005.  
  2006.   /* Breadth first search routines start searching basetypes
  2007.      of TYPE, so we must perform first ply of search here.  */
  2008.   if (dtorp)
  2009.     {
  2010.       if (tree_has_any_destructor_p (binfo, -1))
  2011.     tmp = get_virtual_destructor (binfo, -1);
  2012.  
  2013.       if (tmp)
  2014.     {
  2015.       if (get_base_distance (DECL_CONTEXT (tmp),
  2016.                  DECL_CONTEXT (fndecl), 0, 0) > 0)
  2017.         DECL_CONTEXT (fndecl) = DECL_CONTEXT (tmp);
  2018.       return tmp;
  2019.     }
  2020.  
  2021.       tmp = (tree) breadth_first_search (binfo,
  2022.                      (pfi) get_virtual_destructor,
  2023.                      tree_has_any_destructor_p);
  2024.       if (tmp)
  2025.     {
  2026.       if (get_base_distance (DECL_CONTEXT (tmp),
  2027.                  DECL_CONTEXT (fndecl), 0, 0) > 0)
  2028.         DECL_CONTEXT (fndecl) = DECL_CONTEXT (tmp);
  2029.     }
  2030.       return tmp;
  2031.     }
  2032.   else
  2033.     {
  2034.       tree drettype, dtypes, btypes, instptr_type;
  2035.       tree basetype = DECL_CLASS_CONTEXT (fndecl);
  2036.       tree baselink, best = NULL_TREE;
  2037.       tree name = DECL_ASSEMBLER_NAME (fndecl);
  2038.  
  2039.       declarator = DECL_NAME (fndecl);
  2040.       if (IDENTIFIER_VIRTUAL_P (declarator) == 0)
  2041.     return NULL_TREE;
  2042.  
  2043.       drettype = TREE_TYPE (TREE_TYPE (fndecl));
  2044.       dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
  2045.       if (DECL_STATIC_FUNCTION_P (fndecl))
  2046.     instptr_type = NULL_TREE;
  2047.       else
  2048.     instptr_type = TREE_TYPE (TREE_VALUE (dtypes));
  2049.  
  2050.       for (baselink = get_virtuals_named_this (binfo);
  2051.        baselink; baselink = next_baselink (baselink))
  2052.     {
  2053.       for (tmp = TREE_VALUE (baselink); tmp; tmp = DECL_CHAIN (tmp))
  2054.         {
  2055.           if (! DECL_VINDEX (tmp))
  2056.         continue;
  2057.  
  2058.           btypes = TYPE_ARG_TYPES (TREE_TYPE (tmp));
  2059.           if (instptr_type == NULL_TREE)
  2060.         {
  2061.           if (compparms (TREE_CHAIN (btypes), dtypes, 3))
  2062.             /* Caller knows to give error in this case.  */
  2063.             return tmp;
  2064.           return NULL_TREE;
  2065.         }
  2066.  
  2067.           if ((TYPE_READONLY (TREE_TYPE (TREE_VALUE (btypes)))
  2068.            == TYPE_READONLY (instptr_type))
  2069.           && compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes), 3))
  2070.         {
  2071.           if (IDENTIFIER_ERROR_LOCUS (name) == NULL_TREE
  2072.               && ! comptypes (TREE_TYPE (TREE_TYPE (tmp)), drettype, 1))
  2073.             {
  2074.               cp_error ("conflicting return type specified for virtual function `%D'", fndecl);
  2075.               SET_IDENTIFIER_ERROR_LOCUS (name, basetype);
  2076.             }
  2077.           break;
  2078.         }
  2079.         }
  2080.       if (tmp)
  2081.         {
  2082.           /* If this is ambiguous, we will warn about it later.  */
  2083.           if (best)
  2084.         {
  2085.           if (get_base_distance (DECL_CLASS_CONTEXT (best),
  2086.                      DECL_CLASS_CONTEXT (tmp), 0, 0) > 0)
  2087.             best = tmp;
  2088.         }
  2089.           else
  2090.         best = tmp;
  2091.         }
  2092.     }
  2093.       if (best == NULL_TREE && warn_overloaded_virtual)
  2094.     cp_warning_at ("conflicting specification deriving virtual function `%D'", fndecl);
  2095.  
  2096.       if (best)
  2097.     {
  2098.       if (get_base_distance (DECL_CONTEXT (best),
  2099.                  DECL_CONTEXT (fndecl), 0, 0) > 0)
  2100.         DECL_CONTEXT (fndecl) = DECL_CONTEXT (best);
  2101.     }
  2102.       return best;
  2103.     }
  2104. }
  2105.  
  2106. /* Return the list of virtual functions which are abstract in type TYPE.
  2107.    This information is cached, and so must be built on a
  2108.    non-temporary obstack.  */
  2109. tree
  2110. get_abstract_virtuals (type)
  2111.      tree type;
  2112. {
  2113.   /* For each layer of base class (i.e., the first base class, and each
  2114.      virtual base class from that one), modify the virtual function table
  2115.      of the derived class to contain the new virtual function.
  2116.      A class has as many vfields as it has virtual base classes (total).  */
  2117.   tree vfields, vbases, base, tmp;
  2118.   tree vfield = CLASSTYPE_VFIELD (type);
  2119.   tree fcontext = vfield ? DECL_FCONTEXT (vfield) : NULL_TREE;
  2120.   tree abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (type);
  2121.  
  2122.   for (vfields = CLASSTYPE_VFIELDS (type); vfields; vfields = TREE_CHAIN (vfields))
  2123.     {
  2124.       int normal;
  2125.  
  2126.       /* This code is most likely wrong, and probably only works for single
  2127.      inheritance or by accident. */
  2128.  
  2129.       /* Find the right base class for this derived class, call it BASE.  */
  2130.       base = VF_BASETYPE_VALUE (vfields);
  2131.       if (base == type)
  2132.     continue;
  2133.  
  2134.       /* We call this case NORMAL iff this virtual function table
  2135.      pointer field has its storage reserved in this class.
  2136.      This is normally the case without virtual baseclasses
  2137.      or off-center multiple baseclasses.  */
  2138.       normal = (base == fcontext
  2139.         && (VF_BINFO_VALUE (vfields) == NULL_TREE
  2140.             || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields))));
  2141.  
  2142.       if (normal)
  2143.     tmp = TREE_CHAIN (TYPE_BINFO_VIRTUALS (type));
  2144.       else
  2145.     {
  2146.       /* n.b.: VF_BASETYPE_VALUE (vfields) is the first basetype
  2147.          that provides the virtual function table, whereas
  2148.          VF_DERIVED_VALUE (vfields) is an immediate base type of TYPE
  2149.          that dominates VF_BASETYPE_VALUE (vfields).  The list of
  2150.          vfields we want lies between these two values.  */
  2151.       tree binfo = get_binfo (VF_NORMAL_VALUE (vfields), type, 0);
  2152.       tmp = TREE_CHAIN (BINFO_VIRTUALS (binfo));
  2153.     }
  2154.  
  2155.       /* Get around dossier entry if there is one.  */
  2156.       if (flag_dossier)
  2157.     tmp = TREE_CHAIN (tmp);
  2158.  
  2159.       while (tmp)
  2160.     {
  2161.       tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (tmp));
  2162.       tree base_fndecl = TREE_OPERAND (base_pfn, 0);
  2163.       if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl))
  2164.         abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals);
  2165.       tmp = TREE_CHAIN (tmp);
  2166.     }
  2167.     }
  2168.   for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; vbases = TREE_CHAIN (vbases))
  2169.     {
  2170.       if (! BINFO_VIRTUALS (vbases))
  2171.     continue;
  2172.  
  2173.       tmp = TREE_CHAIN (BINFO_VIRTUALS (vbases));
  2174.       while (tmp)
  2175.     {
  2176.       tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (tmp));
  2177.       tree base_fndecl = TREE_OPERAND (base_pfn, 0);
  2178.       if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl))
  2179.         abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals);
  2180.       tmp = TREE_CHAIN (tmp);
  2181.     }
  2182.     }
  2183.   return nreverse (abstract_virtuals);
  2184. }
  2185.  
  2186. /* For the type TYPE, return a list of member functions available from
  2187.    base classes with name NAME.  The TREE_VALUE of the list is a chain of
  2188.    member functions with name NAME.  The TREE_PURPOSE of the list is a
  2189.    basetype, or a list of base types (in reverse order) which were
  2190.    traversed to reach the chain of member functions.  If we reach a base
  2191.    type which provides a member function of name NAME, and which has at
  2192.    most one base type itself, then we can terminate the search.  */
  2193.  
  2194. tree
  2195. get_baselinks (type_as_binfo_list, type, name)
  2196.      tree type_as_binfo_list;
  2197.      tree type, name;
  2198. {
  2199.   int head = 0, tail = 0, index;
  2200.   tree rval = 0, nval = 0;
  2201.   tree basetypes = type_as_binfo_list;
  2202.   tree binfo = TYPE_BINFO (type);
  2203.  
  2204.   search_stack = push_search_level (search_stack, &search_obstack);
  2205.  
  2206.   while (1)
  2207.     {
  2208.       tree binfos = BINFO_BASETYPES (binfo);
  2209.       int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  2210.  
  2211.       /* Process and/or queue base types.  */
  2212.       for (i = 0; i < n_baselinks; i++)
  2213.     {
  2214.       tree base_binfo = TREE_VEC_ELT (binfos, i);
  2215.       tree btypes;
  2216.  
  2217.       btypes = hash_tree_cons (TREE_VIA_PUBLIC (base_binfo),
  2218.                    TREE_VIA_VIRTUAL (base_binfo),
  2219.                    TREE_VIA_PROTECTED (base_binfo),
  2220.                    NULL_TREE, base_binfo,
  2221.                    basetypes);
  2222.       obstack_ptr_grow (&search_obstack, btypes);
  2223.       search_stack->first = (tree *)obstack_base (&search_obstack);
  2224.       tail += 1;
  2225.     }
  2226.  
  2227.     dont_queue:
  2228.       /* Process head of queue, if one exists.  */
  2229.       if (head >= tail)
  2230.     break;
  2231.  
  2232.       basetypes = search_stack->first[head++];
  2233.       binfo = TREE_VALUE (basetypes);
  2234.       type = BINFO_TYPE (binfo);
  2235.       index = lookup_fnfields_1 (type, name);
  2236.       if (index >= 0)
  2237.     {
  2238.       nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), index);
  2239.       rval = hash_tree_cons (0, 0, 0, basetypes, nval, rval);
  2240.       if (TYPE_BINFO_BASETYPES (type) == 0)
  2241.         goto dont_queue;
  2242.       else if (TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)) == 1)
  2243.         {
  2244.           if (CLASSTYPE_BASELINK_VEC (type))
  2245.         TREE_TYPE (rval) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), index);
  2246.           goto dont_queue;
  2247.         }
  2248.     }
  2249.       nval = NULL_TREE;
  2250.     }
  2251.  
  2252.   search_stack = pop_search_level (search_stack);
  2253.   return rval;
  2254. }
  2255.  
  2256. tree
  2257. next_baselink (baselink)
  2258.      tree baselink;
  2259. {
  2260.   tree tmp = TREE_TYPE (baselink);
  2261.   baselink = TREE_CHAIN (baselink);
  2262.   while (tmp)
  2263.     {
  2264.       /* @@ does not yet add previous base types.  */
  2265.       baselink = tree_cons (TREE_PURPOSE (tmp), TREE_VALUE (tmp),
  2266.                 baselink);
  2267.       TREE_TYPE (baselink) = TREE_TYPE (tmp);
  2268.       tmp = TREE_CHAIN (tmp);
  2269.     }
  2270.   return baselink;
  2271. }
  2272.  
  2273. /* DEPTH-FIRST SEARCH ROUTINES.  */
  2274.  
  2275. /* Assign unique numbers to _CLASSTYPE members of the lattice
  2276.    specified by TYPE.  The root nodes are marked first; the nodes
  2277.    are marked depth-fisrt, left-right.  */
  2278.  
  2279. static int cid;
  2280.  
  2281. /* Matrix implementing a relation from CLASSTYPE X CLASSTYPE => INT.
  2282.    Relation yields 1 if C1 <= C2, 0 otherwise.  */
  2283. typedef char mi_boolean;
  2284. static mi_boolean *mi_matrix;
  2285.  
  2286. /* Type for which this matrix is defined.  */
  2287. static tree mi_type;
  2288.  
  2289. /* Size of the matrix for indexing purposes.  */
  2290. static int mi_size;
  2291.  
  2292. /* Return nonzero if class C2 derives from class C1.  */
  2293. #define BINFO_DERIVES_FROM(C1, C2)    \
  2294.   ((mi_matrix+mi_size*(BINFO_CID (C1)-1))[BINFO_CID (C2)-1])
  2295. #define TYPE_DERIVES_FROM(C1, C2)    \
  2296.   ((mi_matrix+mi_size*(CLASSTYPE_CID (C1)-1))[CLASSTYPE_CID (C2)-1])
  2297. #define BINFO_DERIVES_FROM_STAR(C)    \
  2298.   (mi_matrix+(BINFO_CID (C)-1))
  2299.  
  2300. /* This routine converts a pointer to be a pointer of an immediate
  2301.    base class.  The normal convert_pointer_to routine would diagnose
  2302.    the conversion as ambiguous, under MI code that has the base class
  2303.    as an ambiguous base class. */
  2304. static tree
  2305. convert_pointer_to_single_level (to_type, expr)
  2306.      tree to_type, expr;
  2307. {
  2308.   tree binfo_of_derived;
  2309.   tree last;
  2310.  
  2311.   binfo_of_derived = TYPE_BINFO (TREE_TYPE (TREE_TYPE (expr)));
  2312.   last = get_binfo (to_type, TREE_TYPE (TREE_TYPE (expr)), 0);
  2313.   BINFO_INHERITANCE_CHAIN (last) = binfo_of_derived;
  2314.   BINFO_INHERITANCE_CHAIN (binfo_of_derived) = NULL_TREE;
  2315.   return build_vbase_path (PLUS_EXPR, TYPE_POINTER_TO (to_type), expr, last, 1);
  2316. }
  2317.  
  2318. /* The main function which implements depth first search.
  2319.  
  2320.    This routine has to remember the path it walked up, when
  2321.    dfs_init_vbase_pointers is the work function, as otherwise there
  2322.    would be no record. */
  2323. static void
  2324. dfs_walk (binfo, fn, qfn)
  2325.      tree binfo;
  2326.      void (*fn)();
  2327.      int (*qfn)();
  2328. {
  2329.   tree binfos = BINFO_BASETYPES (binfo);
  2330.   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  2331.  
  2332.   for (i = 0; i < n_baselinks; i++)
  2333.     {
  2334.       tree base_binfo = TREE_VEC_ELT (binfos, i);
  2335.  
  2336.       if ((*qfn)(base_binfo))
  2337.     {
  2338.       if (fn == dfs_init_vbase_pointers)
  2339.         {
  2340.           /* When traversing an arbitrary MI hierarchy, we need to keep
  2341.          a record of the path we took to get down to the final base
  2342.          type, as otherwise there would be no record of it, and just
  2343.          trying to blindly convert at the bottom would be ambiguous.
  2344.  
  2345.          The easiest way is to do the conversions one step at a time,
  2346.          as we know we want the immediate base class at each step.
  2347.  
  2348.          The only special trick to converting one step at a time,
  2349.          is that when we hit the last virtual base class, we must
  2350.          use the SLOT value for it, and not use the normal convert
  2351.          routine.  We use the last virtual base class, as in our
  2352.          implementation, we have pointers to all virtual base
  2353.          classes in the base object.  */
  2354.  
  2355.           tree saved_vbase_decl_ptr_intermediate
  2356.         = vbase_decl_ptr_intermediate;
  2357.  
  2358.           if (TREE_VIA_VIRTUAL (base_binfo))
  2359.         {
  2360.           /* No need for the conversion here, as we know it is the
  2361.              right type.  */
  2362.           vbase_decl_ptr_intermediate
  2363.             = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo));
  2364.         }
  2365.           else
  2366.         {
  2367.           vbase_decl_ptr_intermediate
  2368.             = convert_pointer_to_single_level (BINFO_TYPE (base_binfo),
  2369.                                vbase_decl_ptr_intermediate);
  2370.         }
  2371.  
  2372.           dfs_walk (base_binfo, fn, qfn);
  2373.  
  2374.           vbase_decl_ptr_intermediate = saved_vbase_decl_ptr_intermediate;
  2375.         } else
  2376.           dfs_walk (base_binfo, fn, qfn);
  2377.     }
  2378.     }
  2379.  
  2380.   fn (binfo);
  2381. }
  2382.  
  2383. /* Predicate functions which serve for dfs_walk.  */
  2384. static int numberedp (binfo) tree binfo;
  2385. { return BINFO_CID (binfo); }
  2386. static int unnumberedp (binfo) tree binfo;
  2387. { return BINFO_CID (binfo) == 0; }
  2388.  
  2389. static int markedp (binfo) tree binfo;
  2390. { return BINFO_MARKED (binfo); }
  2391. static int bfs_markedp (binfo, i) tree binfo; int i;
  2392. { return BINFO_MARKED (BINFO_BASETYPE (binfo, i)); }
  2393. static int unmarkedp (binfo) tree binfo;
  2394. { return BINFO_MARKED (binfo) == 0; }
  2395. static int bfs_unmarkedp (binfo, i) tree binfo; int i;
  2396. { return BINFO_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
  2397. static int marked_vtable_pathp (binfo) tree binfo;
  2398. { return BINFO_VTABLE_PATH_MARKED (binfo); }
  2399. static int bfs_marked_vtable_pathp (binfo, i) tree binfo; int i;
  2400. { return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)); }
  2401. static int unmarked_vtable_pathp (binfo) tree binfo;
  2402. { return BINFO_VTABLE_PATH_MARKED (binfo) == 0; }
  2403. static int bfs_unmarked_vtable_pathp (binfo, i) tree binfo; int i;
  2404. { return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
  2405. static int marked_new_vtablep (binfo) tree binfo;
  2406. { return BINFO_NEW_VTABLE_MARKED (binfo); }
  2407. static int bfs_marked_new_vtablep (binfo, i) tree binfo; int i;
  2408. { return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)); }
  2409. static int unmarked_new_vtablep (binfo) tree binfo;
  2410. { return BINFO_NEW_VTABLE_MARKED (binfo) == 0; }
  2411. static int bfs_unmarked_new_vtablep (binfo, i) tree binfo; int i;
  2412. { return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)) == 0; }
  2413.  
  2414. static int dfs_search_slot_nonempty_p (binfo) tree binfo;
  2415. { return CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) != 0; }
  2416.  
  2417. static int dfs_debug_unmarkedp (binfo) tree binfo;
  2418. { return CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo)) == 0; }
  2419.  
  2420. /* The worker functions for `dfs_walk'.  These do not need to
  2421.    test anything (vis a vis marking) if they are paired with
  2422.    a predicate function (above).  */
  2423.  
  2424. /* Assign each type within the lattice a number which is unique
  2425.    in the lattice.  The first number assigned is 1.  */
  2426.  
  2427. static void
  2428. dfs_number (binfo)
  2429.      tree binfo;
  2430. {
  2431.   BINFO_CID (binfo) = ++cid;
  2432. }
  2433.  
  2434. static void
  2435. dfs_unnumber (binfo)
  2436.      tree binfo;
  2437. {
  2438.   BINFO_CID (binfo) = 0;
  2439. }
  2440.  
  2441. static void
  2442. dfs_mark (binfo) tree binfo;
  2443. { SET_BINFO_MARKED (binfo); }
  2444.  
  2445. static void
  2446. dfs_unmark (binfo) tree binfo;
  2447. { CLEAR_BINFO_MARKED (binfo); }
  2448.  
  2449. static void
  2450. dfs_mark_vtable_path (binfo) tree binfo;
  2451. { SET_BINFO_VTABLE_PATH_MARKED (binfo); }
  2452.  
  2453. static void
  2454. dfs_unmark_vtable_path (binfo) tree binfo;
  2455. { CLEAR_BINFO_VTABLE_PATH_MARKED (binfo); }
  2456.  
  2457. static void
  2458. dfs_mark_new_vtable (binfo) tree binfo;
  2459. { SET_BINFO_NEW_VTABLE_MARKED (binfo); }
  2460.  
  2461. static void
  2462. dfs_unmark_new_vtable (binfo) tree binfo;
  2463. { CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); }
  2464.  
  2465. static void
  2466. dfs_clear_search_slot (binfo) tree binfo;
  2467. { CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) = 0; }
  2468.  
  2469. static void
  2470. dfs_debug_mark (binfo)
  2471.      tree binfo;
  2472. {
  2473.   tree t = BINFO_TYPE (binfo);
  2474.  
  2475.   /* Use heuristic that if there are virtual functions,
  2476.      ignore until we see a non-inline virtual function.  */
  2477.   tree methods = CLASSTYPE_METHOD_VEC (t);
  2478.  
  2479.   CLASSTYPE_DEBUG_REQUESTED (t) = 1;
  2480.  
  2481.   /* If interface info is known, the value of (?@@?) is correct.  */
  2482.   if (methods == 0
  2483.       || CLASSTYPE_INTERFACE_KNOWN (t)
  2484.       || (write_virtuals == 2 && TYPE_VIRTUAL_P (t)))
  2485.     return;
  2486.  
  2487.   /* If debug info is requested from this context for this type, supply it.
  2488.      If debug info is requested from another context for this type,
  2489.      see if some third context can supply it.  */
  2490.   if (current_function_decl == NULL_TREE
  2491.       || DECL_CLASS_CONTEXT (current_function_decl) != t)
  2492.     {
  2493.       if (TREE_VEC_ELT (methods, 0))
  2494.     methods = TREE_VEC_ELT (methods, 0);
  2495.       else
  2496.     methods = TREE_VEC_ELT (methods, 1);
  2497.       while (methods)
  2498.     {
  2499.       if (DECL_VINDEX (methods)
  2500.           && DECL_SAVED_INSNS (methods) == 0
  2501.           && DECL_PENDING_INLINE_INFO (methods) == 0
  2502.           && DECL_ABSTRACT_VIRTUAL_P (methods) == 0)
  2503.         {
  2504.           /* Somebody, somewhere is going to have to define this
  2505.          virtual function.  When they do, they will provide
  2506.          the debugging info.  */
  2507.           return;
  2508.         }
  2509.       methods = TREE_CHAIN (methods);
  2510.     }
  2511.     }
  2512.   /* We cannot rely on some alien method to solve our problems,
  2513.      so we must write out the debug info ourselves.  */
  2514.   if (write_symbols != DWARF_DEBUG)
  2515.     DECL_IGNORED_P (TYPE_NAME (t)) = 0;
  2516.   if (! TREE_ASM_WRITTEN (TYPE_NAME (t)))
  2517.     rest_of_type_compilation (t, global_bindings_p ());
  2518. }
  2519.  
  2520. /*  Attach to the type of the virtual base class, the pointer to the
  2521.     virtual base class, given the global pointer vbase_decl_ptr.  */
  2522. static void
  2523. dfs_find_vbases (binfo)
  2524.      tree binfo;
  2525. {
  2526.   tree binfos = BINFO_BASETYPES (binfo);
  2527.   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  2528.  
  2529.   for (i = n_baselinks-1; i >= 0; i--)
  2530.     {
  2531.       tree base_binfo = TREE_VEC_ELT (binfos, i);
  2532.  
  2533.       if (TREE_VIA_VIRTUAL (base_binfo)
  2534.       && CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo)) == 0)
  2535.     {
  2536.       tree vbase = BINFO_TYPE (base_binfo);
  2537.       tree binfo = binfo_member (vbase, vbase_types);
  2538.  
  2539.       CLASSTYPE_SEARCH_SLOT (vbase)
  2540.         = (char *) build (PLUS_EXPR, TYPE_POINTER_TO (vbase),
  2541.                   vbase_decl_ptr, BINFO_OFFSET (binfo));
  2542.     }
  2543.     }
  2544.   SET_BINFO_VTABLE_PATH_MARKED (binfo);
  2545.   SET_BINFO_NEW_VTABLE_MARKED (binfo);
  2546. }
  2547.  
  2548. static void
  2549. dfs_init_vbase_pointers (binfo)
  2550.      tree binfo;
  2551. {
  2552.   tree type = BINFO_TYPE (binfo);
  2553.   tree fields = TYPE_FIELDS (type);
  2554.   tree path, this_vbase_ptr;
  2555.   int distance;
  2556.  
  2557.   CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
  2558.  
  2559.   /* If there is a dossier, it is the first field, though perhaps from
  2560.      the base class.  Otherwise, the first fields are virtual base class
  2561.      pointer fields.  */
  2562.   if (CLASSTYPE_DOSSIER (type) && VFIELD_NAME_P (DECL_NAME (fields)))
  2563.     /* Get past vtable for the object.  */
  2564.     fields = TREE_CHAIN (fields);
  2565.  
  2566.   if (fields == NULL_TREE
  2567.       || DECL_NAME (fields) == NULL_TREE
  2568.       || ! VBASE_NAME_P (DECL_NAME (fields)))
  2569.     return;
  2570.  
  2571.   this_vbase_ptr = vbase_decl_ptr_intermediate;
  2572.  
  2573.   if (TYPE_POINTER_TO (type) != TREE_TYPE (this_vbase_ptr))
  2574.     my_friendly_abort (125);
  2575.  
  2576.   while (fields && DECL_NAME (fields)
  2577.      && VBASE_NAME_P (DECL_NAME (fields)))
  2578.     {
  2579.       tree ref = build (COMPONENT_REF, TREE_TYPE (fields),
  2580.             build_indirect_ref (this_vbase_ptr, NULL_PTR), fields);
  2581.       tree init = (tree)CLASSTYPE_SEARCH_SLOT (TREE_TYPE (TREE_TYPE (fields)));
  2582.       vbase_init_result = tree_cons (binfo_member (TREE_TYPE (TREE_TYPE (fields)),
  2583.                            vbase_types),
  2584.                      build_modify_expr (ref, NOP_EXPR, init),
  2585.                      vbase_init_result);
  2586.       fields = TREE_CHAIN (fields);
  2587.     }
  2588. }
  2589.  
  2590. /* Sometimes this needs to clear both VTABLE_PATH and NEW_VTABLE.  Other
  2591.    times, just NEW_VTABLE, but optimizer should make both with equal
  2592.    efficiency (though it does not currently).  */
  2593. static void
  2594. dfs_clear_vbase_slots (binfo)
  2595.      tree binfo;
  2596. {
  2597.   tree type = BINFO_TYPE (binfo);
  2598.   CLASSTYPE_SEARCH_SLOT (type) = 0;
  2599.   CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
  2600.   CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
  2601. }
  2602.  
  2603. tree
  2604. init_vbase_pointers (type, decl_ptr)
  2605.      tree type;
  2606.      tree decl_ptr;
  2607. {
  2608.   if (TYPE_USES_VIRTUAL_BASECLASSES (type))
  2609.     {
  2610.       int old_flag = flag_this_is_variable;
  2611.       tree binfo = TYPE_BINFO (type);
  2612.       flag_this_is_variable = -2;
  2613.       vbase_types = CLASSTYPE_VBASECLASSES (type);
  2614.       vbase_decl_ptr = decl_ptr;
  2615.       vbase_decl = build_indirect_ref (decl_ptr, NULL_PTR);
  2616.       vbase_decl_ptr_intermediate = vbase_decl_ptr;
  2617.       vbase_init_result = NULL_TREE;
  2618.       dfs_walk (binfo, dfs_find_vbases, unmarked_vtable_pathp);
  2619.       dfs_walk (binfo, dfs_init_vbase_pointers, marked_vtable_pathp);
  2620.       dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep);
  2621.       flag_this_is_variable = old_flag;
  2622.       return vbase_init_result;
  2623.     }
  2624.   return 0;
  2625. }
  2626.  
  2627. /* Build a COMPOUND_EXPR which when expanded will generate the code
  2628.    needed to initialize all the virtual function table slots of all
  2629.    the virtual baseclasses.  FOR_TYPE is the type which determines the
  2630.    virtual baseclasses to use; TYPE is the type of the object to which
  2631.    the initialization applies.  TRUE_EXP is the true object we are
  2632.    initializing, and DECL_PTR is the pointer to the sub-object we
  2633.    are initializing.
  2634.  
  2635.    When USE_COMPUTED_OFFSETS is non-zero, we can assume that the
  2636.    object was laidout by a top-level contructor and the computed
  2637.    offsets are valid to store vtables.  When zero, we must store new
  2638.    vtables through virtual baseclass pointers.  */
  2639.  
  2640. tree
  2641. build_vbase_vtables_init (main_binfo, binfo, true_exp, decl_ptr,
  2642.               use_computed_offsets)
  2643.      tree main_binfo, binfo;
  2644.      tree true_exp, decl_ptr;
  2645.      int use_computed_offsets;
  2646. {
  2647.   tree for_type = BINFO_TYPE (main_binfo);
  2648.   tree type = BINFO_TYPE (binfo);
  2649.   if (TYPE_USES_VIRTUAL_BASECLASSES (type))
  2650.     {
  2651.       int old_flag = flag_this_is_variable;
  2652.       tree vtable_init_result = NULL_TREE;
  2653.       tree vbases = CLASSTYPE_VBASECLASSES (type);
  2654.  
  2655.       vbase_types = CLASSTYPE_VBASECLASSES (for_type);
  2656.       vbase_decl_ptr = true_exp ? build_unary_op (ADDR_EXPR, true_exp, 0) : decl_ptr;
  2657.       vbase_decl = true_exp ? true_exp : build_indirect_ref (decl_ptr, NULL_PTR);
  2658.  
  2659.       if (use_computed_offsets)
  2660.     {
  2661.       /* This is an object of type IN_TYPE,  */
  2662.       flag_this_is_variable = -2;
  2663.       dfs_walk (main_binfo, dfs_find_vbases, unmarked_new_vtablep);
  2664.     }
  2665.  
  2666.       /* Initialized with vtables of type TYPE.  */
  2667.       while (vbases)
  2668.     {
  2669.       /* This time through, not every class's vtable
  2670.          is going to be initialized.  That is, we only initialize
  2671.          the "last" vtable pointer.  */
  2672.  
  2673.       if (CLASSTYPE_VSIZE (BINFO_TYPE (vbases)))
  2674.         {
  2675.           tree addr;
  2676.           tree vtbl = BINFO_VTABLE (vbases);
  2677.           tree init = build_unary_op (ADDR_EXPR, vtbl, 0);
  2678.           assemble_external (vtbl);
  2679.           TREE_USED (vtbl) = 1;
  2680.  
  2681.           if (use_computed_offsets)
  2682.         addr = (tree)CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbases));
  2683.           else
  2684.         addr = convert_pointer_to (vbases, vbase_decl_ptr);
  2685.  
  2686.           if (addr)
  2687.         {
  2688.           tree ref = build_vfield_ref (build_indirect_ref (addr, NULL_PTR),
  2689.                            BINFO_TYPE (vbases));
  2690.           init = convert_force (TREE_TYPE (ref), init);
  2691.           vtable_init_result = tree_cons (NULL_TREE, build_modify_expr (ref, NOP_EXPR, init),
  2692.                           vtable_init_result);
  2693.         }
  2694.         }
  2695.       vbases = TREE_CHAIN (vbases);
  2696.     }
  2697.  
  2698.       dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep);
  2699.  
  2700.       flag_this_is_variable = old_flag;
  2701.       if (vtable_init_result)
  2702.     return build_compound_expr (vtable_init_result);
  2703.     }
  2704.   return error_mark_node;
  2705. }
  2706.  
  2707. void
  2708. clear_search_slots (type)
  2709.      tree type;
  2710. {
  2711.   dfs_walk (TYPE_BINFO (type),
  2712.         dfs_clear_search_slot, dfs_search_slot_nonempty_p);
  2713. }
  2714.  
  2715. /* get virtual base class types.
  2716.    This adds type to the vbase_types list in reverse dfs order.
  2717.    Ordering is very important, so don't change it.  */
  2718.  
  2719. static void
  2720. dfs_get_vbase_types (binfo)
  2721.      tree binfo;
  2722. {
  2723.   tree binfos = BINFO_BASETYPES (binfo);
  2724.   tree type = BINFO_TYPE (binfo);
  2725.   tree these_vbase_types = CLASSTYPE_VBASECLASSES (type);
  2726.   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  2727.  
  2728.   if (these_vbase_types)
  2729.     {
  2730.       while (these_vbase_types)
  2731.     {
  2732.       tree this_type = BINFO_TYPE (these_vbase_types);
  2733.  
  2734.       /* We really need to start from a fresh copy of this
  2735.          virtual basetype!  CLASSTYPE_MARKED2 is the shortcut
  2736.          for BINFO_VBASE_MARKED.  */
  2737.       if (! CLASSTYPE_MARKED2 (this_type))
  2738.         {
  2739.           vbase_types = make_binfo (integer_zero_node,
  2740.                     this_type,
  2741.                     TYPE_BINFO_VTABLE (this_type),
  2742.                     TYPE_BINFO_VIRTUALS (this_type),
  2743.                     vbase_types);
  2744.           TREE_VIA_VIRTUAL (vbase_types) = 1;
  2745.           SET_CLASSTYPE_MARKED2 (this_type);
  2746.         }
  2747.       these_vbase_types = TREE_CHAIN (these_vbase_types);
  2748.     }
  2749.     }
  2750.   else for (i = 0; i < n_baselinks; i++)
  2751.     {
  2752.       tree base_binfo = TREE_VEC_ELT (binfos, i);
  2753.       if (TREE_VIA_VIRTUAL (base_binfo) && ! BINFO_VBASE_MARKED (base_binfo))
  2754.     {
  2755.       vbase_types = make_binfo (integer_zero_node, BINFO_TYPE (base_binfo),
  2756.                     BINFO_VTABLE (base_binfo),
  2757.                     BINFO_VIRTUALS (base_binfo), vbase_types);
  2758.       TREE_VIA_VIRTUAL (vbase_types) = 1;
  2759.       SET_BINFO_VBASE_MARKED (base_binfo);
  2760.     }
  2761.     }
  2762.   SET_BINFO_MARKED (binfo);
  2763. }
  2764.  
  2765. /* Some virtual baseclasses might be virtual baseclasses for
  2766.    other virtual baseclasses.  We sort the virtual baseclasses
  2767.    topologically: in the list returned, the first virtual base
  2768.    classes have no virtual baseclasses themselves, and any entry
  2769.    on the list has no dependency on virtual base classes later in the
  2770.    list.  */
  2771. tree
  2772. get_vbase_types (type)
  2773.      tree type;
  2774. {
  2775.   tree ordered_vbase_types = NULL_TREE, prev, next;
  2776.   tree vbases;
  2777.  
  2778.   vbase_types = NULL_TREE;
  2779.   dfs_walk (TYPE_BINFO (type), dfs_get_vbase_types, unmarkedp);
  2780.   dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp);
  2781.   /* Rely upon the reverse dfs ordering from dfs_get_vbase_types, and now
  2782.      reverse it so that we get normal dfs ordering.  */
  2783.   vbase_types = nreverse (vbase_types);
  2784.  
  2785.   /* Almost all of the below is not needed now.  We should be able to just
  2786.      return vbase_types directly... (mrs) */
  2787.   while (vbase_types)
  2788.     {
  2789.       /* Now sort these types.  This is essentially a bubble merge.  */
  2790.  
  2791.       /* Farm out virtual baseclasses which have no marked ancestors.  */
  2792.       for (vbases = vbase_types, prev = NULL_TREE;
  2793.        vbases; vbases = next)
  2794.     {
  2795.       next = TREE_CHAIN (vbases);
  2796.       /* If VBASES does not have any vbases itself, or it's
  2797.          topologically safe, it goes into the sorted list.  */
  2798.       if (1 /* ANSI C++ specifies dfs ordering now. */
  2799.           || ! CLASSTYPE_VBASECLASSES (BINFO_TYPE (vbases))
  2800.           || BINFO_VBASE_MARKED (vbases) == 0)
  2801.         {
  2802.           if (prev)
  2803.         TREE_CHAIN (prev) = TREE_CHAIN (vbases);
  2804.           else
  2805.         vbase_types = TREE_CHAIN (vbases);
  2806.           TREE_CHAIN (vbases) = NULL_TREE;
  2807.           ordered_vbase_types = chainon (ordered_vbase_types, vbases);
  2808.           CLEAR_BINFO_VBASE_MARKED (vbases);
  2809.         }
  2810.       else
  2811.         prev = vbases;
  2812.     }
  2813.  
  2814.       /* Now unmark types all of whose ancestors are now on the
  2815.      `ordered_vbase_types' list.  */
  2816.       for (vbases = vbase_types; vbases; vbases = TREE_CHAIN (vbases))
  2817.     {
  2818.       /* If all our virtual baseclasses are unmarked, ok.  */
  2819.       tree t = CLASSTYPE_VBASECLASSES (BINFO_TYPE (vbases));
  2820.       while (t && (BINFO_VBASE_MARKED (t) == 0
  2821.                || ! CLASSTYPE_VBASECLASSES (BINFO_TYPE (t))))
  2822.         t = TREE_CHAIN (t);
  2823.       if (t == NULL_TREE)
  2824.         CLEAR_BINFO_VBASE_MARKED (vbases);
  2825.     }
  2826.     }
  2827.  
  2828.   return ordered_vbase_types;
  2829. }
  2830.  
  2831. static void
  2832. dfs_record_inheritance (binfo)
  2833.      tree binfo;
  2834. {
  2835.   tree binfos = BINFO_BASETYPES (binfo);
  2836.   int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
  2837.   mi_boolean *derived_row = BINFO_DERIVES_FROM_STAR (binfo);
  2838.  
  2839.   for (i = n_baselinks-1; i >= 0; i--)
  2840.     {
  2841.       int j;
  2842.       tree base_binfo = TREE_VEC_ELT (binfos, i);
  2843.       tree baseclass = BINFO_TYPE (base_binfo);
  2844.       mi_boolean *base_row = BINFO_DERIVES_FROM_STAR (base_binfo);
  2845.  
  2846.       /* Don't search if there's nothing there!  MI_SIZE can be
  2847.      zero as a result of parse errors.  */
  2848.       if (TYPE_BINFO_BASETYPES (baseclass) && mi_size > 0)
  2849.     for (j = mi_size*(CLASSTYPE_CID (baseclass)-1); j >= 0; j -= mi_size)
  2850.       derived_row[j] |= base_row[j];
  2851.       TYPE_DERIVES_FROM (baseclass, BINFO_TYPE (binfo)) = 1;
  2852.     }
  2853.  
  2854.   SET_BINFO_MARKED (binfo);
  2855. }
  2856.  
  2857. /* Given a _CLASSTYPE node in a multiple inheritance lattice,
  2858.    convert the lattice into a simple relation such that,
  2859.    given to CIDs, C1 and C2, one can determine if C1 <= C2
  2860.    or C2 <= C1 or C1 <> C2.
  2861.  
  2862.    Once constructed, we walk the lattice depth fisrt,
  2863.    applying various functions to elements as they are encountered.
  2864.  
  2865.    We use xmalloc here, in case we want to randomly free these tables.  */
  2866.  
  2867. #define SAVE_MI_MATRIX
  2868.  
  2869. void
  2870. build_mi_matrix (type)
  2871.      tree type;
  2872. {
  2873.   tree binfo = TYPE_BINFO (type);
  2874.   cid = 0;
  2875.  
  2876. #ifdef SAVE_MI_MATRIX
  2877.   if (CLASSTYPE_MI_MATRIX (type))
  2878.     {
  2879.       mi_size = CLASSTYPE_N_SUPERCLASSES (type) + CLASSTYPE_N_VBASECLASSES (type);
  2880.       mi_matrix = CLASSTYPE_MI_MATRIX (type);
  2881.       mi_type = type;
  2882.       dfs_walk (binfo, dfs_number, unnumberedp);
  2883.       return;
  2884.     }
  2885. #endif
  2886.  
  2887.   mi_size = CLASSTYPE_N_SUPERCLASSES (type) + CLASSTYPE_N_VBASECLASSES (type);
  2888.   mi_matrix = (char *)xmalloc ((mi_size + 1) * (mi_size + 1));
  2889.   mi_type = type;
  2890.   bzero (mi_matrix, (mi_size + 1) * (mi_size + 1));
  2891.   dfs_walk (binfo, dfs_number, unnumberedp);
  2892.   dfs_walk (binfo, dfs_record_inheritance, unmarkedp);
  2893.   dfs_walk (binfo, dfs_unmark, markedp);
  2894. }
  2895.  
  2896. void
  2897. free_mi_matrix ()
  2898. {
  2899.   dfs_walk (TYPE_BINFO (mi_type), dfs_unnumber, numberedp);
  2900.  
  2901. #ifdef SAVE_MI_MATRIX
  2902.   CLASSTYPE_MI_MATRIX (mi_type) = mi_matrix;
  2903. #else
  2904.   free (mi_matrix);
  2905.   mi_size = 0;
  2906.   cid = 0;
  2907. #endif
  2908. }
  2909.  
  2910. /* Local variables for detecting ambiguities of virtual functions
  2911.    when two or more classes are joined at a multiple inheritance
  2912.    seam.  */
  2913. typedef struct {
  2914.   tree decl;
  2915.   tree args;
  2916.   tree ptr;
  2917. } mi_ventry;
  2918. static mi_ventry *mi_vmatrix;
  2919. static int *mi_vmax;
  2920. static int mi_vrows, mi_vcols;
  2921. #define MI_VMATRIX(ROW,COL) ((mi_vmatrix + (ROW)*mi_vcols)[COL])
  2922.  
  2923. /* Build a table of virtual functions for a multiple-inheritance
  2924.    structure.  Here, there are N base classes, and at most
  2925.    M entries per class.
  2926.  
  2927.    This function does nothing if N is 0 or 1.  */
  2928. void
  2929. build_mi_virtuals (rows, cols)
  2930.      int rows, cols;
  2931. {
  2932.   if (rows < 2 || cols == 0)
  2933.     return;
  2934.   mi_vrows = rows;
  2935.   mi_vcols = cols;
  2936.   mi_vmatrix = (mi_ventry *)xmalloc ((rows+1) * cols * sizeof (mi_ventry));
  2937.   mi_vmax = (int *)xmalloc ((rows+1) * sizeof (int));
  2938.  
  2939.   bzero (mi_vmax, rows * sizeof (int));
  2940.  
  2941.   /* Row indices start at 1, so adjust this.  */
  2942.   mi_vmatrix -= cols;
  2943.   mi_vmax -= 1;
  2944. }
  2945.  
  2946. /* Comparison function for ordering virtual function table entries.  */
  2947. static int
  2948. rank_mi_virtuals (v1, v2)
  2949.      mi_ventry *v1, *v2;
  2950. {
  2951.   tree p1, p2;
  2952.   int i;
  2953.  
  2954.   i = (long) (DECL_NAME (v1->decl)) - (long) (DECL_NAME (v2->decl));
  2955.   if (i)
  2956.     return i;
  2957.   p1 = v1->args;
  2958.   p2 = v2->args;
  2959.  
  2960.   if (p1 == p2)
  2961.     return 0;
  2962.  
  2963.   while (p1 && p2)
  2964.     {
  2965.       i = ((long) (TREE_VALUE (p1)) - (long) (TREE_VALUE (p2)));
  2966.       if (i)
  2967.     return i;
  2968.  
  2969.       if (TREE_CHAIN (p1))
  2970.     {
  2971.       if (! TREE_CHAIN (p2))
  2972.         return 1;
  2973.       p1 = TREE_CHAIN (p1);
  2974.       p2 = TREE_CHAIN (p2);
  2975.     }
  2976.       else if (TREE_CHAIN (p2))
  2977.     return -1;
  2978.       else
  2979.     {
  2980.       /* When matches of argument lists occur, pick lowest
  2981.          address to keep searching time to a minimum on
  2982.          later passes--like hashing, only different.
  2983.          *MUST BE STABLE*.  */
  2984.       if ((long) (v2->args) < (long) (v1->args))
  2985.         v1->args = v2->args;
  2986.       else
  2987.         v2->args = v1->args;
  2988.       return 0;
  2989.     }
  2990.     }
  2991.   return 0;
  2992. }
  2993.  
  2994. /* Install the virtuals functions got from the initializer VIRTUALS to
  2995.    the table at index ROW.  */
  2996. void
  2997. add_mi_virtuals (row, virtuals)
  2998.      int row;
  2999.      tree virtuals;
  3000. {
  3001.   int col = 0;
  3002.  
  3003.   if (mi_vmatrix == 0)
  3004.     return;
  3005.   while (virtuals)
  3006.     {
  3007.       tree decl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0);
  3008.       MI_VMATRIX (row, col).decl = decl;
  3009.       MI_VMATRIX (row, col).args = FUNCTION_ARG_CHAIN (decl);
  3010.       MI_VMATRIX (row, col).ptr = TREE_VALUE (virtuals);
  3011.       virtuals = TREE_CHAIN (virtuals);
  3012.       col += 1;
  3013.     }
  3014.   mi_vmax[row] = col;
  3015.  
  3016.   qsort (mi_vmatrix + row * mi_vcols,
  3017.      col,
  3018.      sizeof (mi_ventry),
  3019.      rank_mi_virtuals);
  3020. }
  3021.  
  3022. /* If joining two types results in an ambiguity in the virtual
  3023.    function table, report such here.  */
  3024. void
  3025. report_ambiguous_mi_virtuals (rows, type)
  3026.      int rows;
  3027.      tree type;
  3028. {
  3029.   int *mi_vmin;
  3030.   int row1, col1, row, col;
  3031.  
  3032.   if (mi_vmatrix == 0)
  3033.     return;
  3034.  
  3035.   /* Now virtuals are all sorted, so we merge to find ambiguous cases.  */
  3036.   mi_vmin = (int *)alloca ((rows+1) * sizeof (int));
  3037.   bzero (mi_vmin, rows * sizeof (int));
  3038.  
  3039.   /* adjust.  */
  3040.   mi_vmin -= 1;
  3041.  
  3042.   /* For each base class with virtual functions (and this includes views
  3043.      of the virtual baseclasses from different base classes), see that
  3044.      each virtual function in that base class has a unique meet.
  3045.  
  3046.      When the column loop is finished, THIS_DECL is in fact the meet.
  3047.      If that value does not appear in the virtual function table for
  3048.      the row, install it.  This happens when that virtual function comes
  3049.      from a virtual baseclass, or a non-leftmost baseclass.  */
  3050.  
  3051.   for (row1 = 1; row1 < rows; row1++)
  3052.     {
  3053.       tree this_decl = 0;
  3054.  
  3055.       for (col1 = mi_vmax[row1]-1; col1 >= mi_vmin[row1]; col1--)
  3056.     {
  3057.       tree these_args = MI_VMATRIX (row1, col1).args;
  3058.       tree this_context;
  3059.  
  3060.       this_decl = MI_VMATRIX (row1, col1).decl;
  3061.       if (this_decl == 0)
  3062.         continue;
  3063.       this_context = TYPE_BINFO (DECL_CLASS_CONTEXT (this_decl));
  3064.  
  3065.       if (this_context != TYPE_BINFO (type))
  3066.         this_context = get_binfo (this_context, type, 0);
  3067.  
  3068.       for (row = row1+1; row <= rows; row++)
  3069.         for (col = mi_vmax[row]-1; col >= mi_vmin[row]; col--)
  3070.           {
  3071.         mi_ventry this_entry;
  3072.  
  3073.         if (MI_VMATRIX (row, col).decl == 0)
  3074.           continue;
  3075.  
  3076.         this_entry.decl = this_decl;
  3077.         this_entry.args = these_args;
  3078.         this_entry.ptr = MI_VMATRIX (row1, col1).ptr;
  3079.         if (rank_mi_virtuals (&this_entry, &MI_VMATRIX (row, col)) == 0)
  3080.           {
  3081.             /* They are equal.  There are four possibilities:
  3082.  
  3083.                (1) Derived class is defining this virtual function.
  3084.                (2) Two paths to the same virtual function in the
  3085.                same base class.
  3086.                (3) A path to a virtual function declared in one base
  3087.                class, and another path to a virtual function in a
  3088.                base class of the base class.
  3089.                (4) Two paths to the same virtual function in different
  3090.                base classes.
  3091.  
  3092.                The first three cases are ok (non-ambiguous).  */
  3093.  
  3094.             tree that_context, tmp;
  3095.             int this_before_that;
  3096.  
  3097.             if (type == BINFO_TYPE (this_context))
  3098.               /* case 1.  */
  3099.               goto ok;
  3100.             that_context = get_binfo (DECL_CLASS_CONTEXT (MI_VMATRIX (row, col).decl), type, 0);
  3101.             if (that_context == this_context)
  3102.               /* case 2.  */
  3103.               goto ok;
  3104.             if (that_context != NULL_TREE)
  3105.               {
  3106.             tmp = get_binfo (that_context, this_context, 0);
  3107.             this_before_that = (that_context != tmp);
  3108.             if (this_before_that == 0)
  3109.               /* case 3a.  */
  3110.               goto ok;
  3111.             tmp = get_binfo (this_context, that_context, 0);
  3112.             this_before_that = (this_context == tmp);
  3113.             if (this_before_that != 0)
  3114.               /* case 3b.  */
  3115.               goto ok;
  3116.  
  3117.             /* case 4.  */
  3118.             /* These two are not hard errors, but could be
  3119.                symptoms of bad code.  The resultant code
  3120.                the compiler generates needs to be checked.
  3121.                (mrs) */
  3122. #if 0
  3123.             cp_error_at ("ambiguous virtual function `%s'",
  3124.                        MI_VMATRIX (row, col).decl);
  3125.             cp_error_at ("ambiguating function `%D' (joined by type `%T')", this_decl, current_class_name);
  3126. #endif
  3127.               }
  3128.           ok:
  3129.             MI_VMATRIX (row, col).decl = 0;
  3130.  
  3131.             /* Let zeros propagate.  */
  3132.             if (col == mi_vmax[row]-1)
  3133.               {
  3134.             int i = col;
  3135.             while (i >= mi_vmin[row]
  3136.                    && MI_VMATRIX (row, i).decl == 0)
  3137.               i--;
  3138.             mi_vmax[row] = i+1;
  3139.               }
  3140.             else if (col == mi_vmin[row])
  3141.               {
  3142.             int i = col;
  3143.             while (i < mi_vmax[row]
  3144.                    && MI_VMATRIX (row, i).decl == 0)
  3145.               i++;
  3146.             mi_vmin[row] = i;
  3147.               }
  3148.           }
  3149.           }
  3150.     }
  3151.     }
  3152.   free (mi_vmatrix + mi_vcols);
  3153.   mi_vmatrix = 0;
  3154.   free (mi_vmax + 1);
  3155.   mi_vmax = 0;
  3156. }
  3157.  
  3158. /* If we want debug info for a type TYPE, make sure all its base types
  3159.    are also marked as being potentially interesting.  This avoids
  3160.    the problem of not writing any debug info for intermediate basetypes
  3161.    that have abstract virtual functions.  */
  3162.  
  3163. void
  3164. note_debug_info_needed (type)
  3165.      tree type;
  3166. {
  3167.   dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp);
  3168. }
  3169.  
  3170. /* Subroutines of push_class_decls ().  */
  3171.  
  3172. /* Add the instance variables which this class contributed to the
  3173.    current class binding contour.  When a redefinition occurs,
  3174.    if the redefinition is strictly within a single inheritance path,
  3175.    we just overwrite (in the case of a data field) or
  3176.    cons (in the case of a member function) the old declaration with
  3177.    the new.  If the fields are not within a single inheritance path,
  3178.    we must cons them in either case.
  3179.  
  3180.    when NEW_CLASS_SCOPING is 1:
  3181.  
  3182.    In order to know what decls are new (stemming from the current
  3183.    invocation of push_class_decls) we enclose them in an "envelope",
  3184.    which is a TREE_LIST node where the TREE_PURPOSE slot contains the
  3185.    new decl (or possibly a list of competing ones), the TREE_VALUE slot
  3186.    points to the old value and the TREE_CHAIN slot chains together all
  3187.    envelopes which needs to be "opened" in push_class_decls.  Opening an
  3188.    envelope means: push the old value onto the class_shadowed list,
  3189.    install the new one and if it's a TYPE_DECL do the same to the
  3190.    IDENTIFIER_TYPE_VALUE.  Such an envelope is recognized by seeing that
  3191.    the TREE_PURPOSE slot is non-null, and that it is not an identifier.
  3192.    Because if it is, it could be a set of overloaded methods from an
  3193.    outer scope.  */
  3194.  
  3195. static void
  3196. dfs_pushdecls (binfo)
  3197.      tree binfo;
  3198. {
  3199.   tree type = BINFO_TYPE (binfo);
  3200.   tree fields, *methods, *end;
  3201.   tree method_vec;
  3202.  
  3203.   for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
  3204.     {
  3205.       /* Unmark so that if we are in a constructor, and then find that
  3206.      this field was initialized by a base initializer,
  3207.      we can emit an error message.  */
  3208.       if (TREE_CODE (fields) == FIELD_DECL)
  3209.     TREE_USED (fields) = 0;
  3210.  
  3211.       /* Recurse into anonymous unions.  */
  3212.       if (DECL_NAME (fields) == NULL_TREE
  3213.       && TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE)
  3214.     {
  3215.       dfs_pushdecls (TYPE_BINFO (TREE_TYPE (fields)));
  3216.       continue;
  3217.     }
  3218.  
  3219.       if (TREE_CODE (fields) != TYPE_DECL)
  3220.     {
  3221.       DECL_PUBLIC (fields) = 0;
  3222.       DECL_PROTECTED (fields) = 0;
  3223.       DECL_PRIVATE (fields) = 0;
  3224.     }
  3225.  
  3226.       if (DECL_NAME (fields))
  3227.     {
  3228. #if NEW_CLASS_SCOPING
  3229.       tree class_value = IDENTIFIER_CLASS_VALUE (DECL_NAME (fields));
  3230.  
  3231.       /* If the class value is an envelope of the kind described in
  3232.          the comment above, we try to rule out possible ambiguities.
  3233.          If we can't do that, keep a TREE_LIST with possibly ambiguous
  3234.          decls in there.  */
  3235.       if (class_value && TREE_CODE (class_value) == TREE_LIST
  3236.           && TREE_PURPOSE (class_value) != NULL_TREE
  3237.           && (TREE_CODE (TREE_PURPOSE (class_value))
  3238.           != IDENTIFIER_NODE))
  3239.         {
  3240.           tree value = TREE_PURPOSE (class_value);
  3241. #else
  3242.       tree value = IDENTIFIER_CLASS_VALUE (DECL_NAME (fields));
  3243.       if (value)
  3244.         {
  3245. #endif
  3246.           tree context;
  3247.  
  3248.           /* Possible ambiguity.  If its defining type(s)
  3249.          is (are all) derived from us, no problem.  */
  3250.           if (TREE_CODE (value) != TREE_LIST)
  3251.         {
  3252.           context = (TREE_CODE (value) == FUNCTION_DECL
  3253.                  && DECL_VIRTUAL_P (value))
  3254.             ? DECL_CLASS_CONTEXT (value)
  3255.               : DECL_CONTEXT (value);
  3256.  
  3257.           if (context && (context == type
  3258.                   || TYPE_DERIVES_FROM (context, type)))
  3259.             value = fields;
  3260.           else
  3261.             value = tree_cons (NULL_TREE, fields,
  3262.                        build_tree_list (NULL_TREE, value));
  3263.         }
  3264.           else
  3265.         {
  3266.           /* All children may derive from us, in which case
  3267.              there is no problem.  Otherwise, we have to
  3268.              keep lists around of what the ambiguities might be.  */
  3269.           tree values;
  3270.           int problem = 0;
  3271.  
  3272.           for (values = value; values; values = TREE_CHAIN (values))
  3273.             {
  3274.               tree sub_values = TREE_VALUE (values);
  3275.  
  3276.               if (TREE_CODE (sub_values) == TREE_LIST)
  3277.             {
  3278.               for (; sub_values; sub_values = TREE_CHAIN (sub_values))
  3279.                 {
  3280.                   register tree list_mbr = TREE_VALUE (sub_values);
  3281.  
  3282.                   context = (TREE_CODE (list_mbr) == FUNCTION_DECL
  3283.                      && DECL_VIRTUAL_P (list_mbr))
  3284.                 ? DECL_CLASS_CONTEXT (list_mbr)
  3285.                   : DECL_CONTEXT (list_mbr);
  3286.  
  3287.                   if (! TYPE_DERIVES_FROM (context, type))
  3288.                 {
  3289.                   value = tree_cons (NULL_TREE, TREE_VALUE (values), value);
  3290.                   problem = 1;
  3291.                   break;
  3292.                 }
  3293.                 }
  3294.             }
  3295.               else
  3296.             {
  3297.               context = (TREE_CODE (sub_values) == FUNCTION_DECL
  3298.                      && DECL_VIRTUAL_P (sub_values))
  3299.                 ? DECL_CLASS_CONTEXT (sub_values)
  3300.                   : DECL_CONTEXT (sub_values);
  3301.  
  3302.               if (context && ! TYPE_DERIVES_FROM (context, type))
  3303.                 {
  3304.                   value = tree_cons (NULL_TREE, values, value);
  3305.                   problem = 1;
  3306.                   break;
  3307.                 }
  3308.             }
  3309.             }
  3310.           if (! problem) value = fields;
  3311.         }
  3312.  
  3313.           /* Mark this as a potentially ambiguous member.  */
  3314.           if (TREE_CODE (value) == TREE_LIST)
  3315.         {
  3316.           /* Leaving TREE_TYPE blank is intentional.
  3317.              We cannot use `error_mark_node' (lookup_name)
  3318.              or `unknown_type_node' (all member functions use this).  */
  3319.           TREE_NONLOCAL_FLAG (value) = 1;
  3320.         }
  3321.  
  3322. #if NEW_CLASS_SCOPING
  3323.           /* Put the new contents in our envelope.  */
  3324.           TREE_PURPOSE (class_value) = value;
  3325.         }
  3326.       else
  3327.         {
  3328.           /* See comment above for a description of envelopes.  */
  3329.           tree envelope = tree_cons (fields, class_value,
  3330.                      closed_envelopes);
  3331.  
  3332.           closed_envelopes = envelope;
  3333.           IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) = envelope;
  3334.         }
  3335. #else
  3336.           IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) = value;
  3337.         }
  3338.       else IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) = fields;
  3339. #endif
  3340.     }
  3341.     }
  3342.  
  3343.   method_vec = CLASSTYPE_METHOD_VEC (type);
  3344.   if (method_vec != 0)
  3345.     {
  3346.       /* Farm out constructors and destructors.  */
  3347.       methods = &TREE_VEC_ELT (method_vec, 1);
  3348.       end = TREE_VEC_END (method_vec);
  3349.  
  3350.       /* This does not work for multiple inheritance yet.  */
  3351.       while (methods != end)
  3352.     {
  3353.       /* This will cause lookup_name to return a pointer
  3354.          to the tree_list of possible methods of this name.
  3355.          If the order is a problem, we can nreverse them.  */
  3356.       tree tmp;
  3357. #if NEW_CLASS_SCOPING
  3358.       tree class_value = IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods));
  3359.  
  3360.       if (class_value && TREE_CODE (class_value) == TREE_LIST
  3361.           && TREE_PURPOSE (class_value) != NULL_TREE
  3362.           && TREE_CODE (TREE_PURPOSE (class_value)) != IDENTIFIER_NODE)
  3363.         {
  3364.           tree old = TREE_PURPOSE (class_value);
  3365.  
  3366.           maybe_push_cache_obstack ();
  3367.           if (TREE_CODE (old) == TREE_LIST)
  3368.         tmp = tree_cons (DECL_NAME (*methods), *methods, old);
  3369.           else
  3370.         {
  3371.           /* Only complain if we shadow something we can access.  */
  3372.           if (old
  3373.               && ((DECL_LANG_SPECIFIC (old)
  3374.                && DECL_CLASS_CONTEXT (old) == current_class_type)
  3375.               || ! TREE_PRIVATE (old)))
  3376.             /* Should figure out visibility more accurately.  */
  3377.             cp_warning ("shadowing member `%#D' with member function `%#D'",
  3378.                 old, *methods);
  3379.           tmp = build_tree_list (DECL_NAME (*methods), *methods);
  3380.         }
  3381.           pop_obstacks ();
  3382.  
  3383.           TREE_TYPE (tmp) = unknown_type_node;
  3384. #if 0
  3385.           TREE_OVERLOADED (tmp) = DECL_OVERLOADED (*methods);
  3386. #endif
  3387.           TREE_NONLOCAL_FLAG (tmp) = 1;
  3388.           
  3389.           /* Put the new contents in our envelope.  */
  3390.           TREE_PURPOSE (class_value) = tmp;
  3391.         }
  3392.       else
  3393.         {
  3394.           maybe_push_cache_obstack ();
  3395.           tmp = build_tree_list (DECL_NAME (*methods), *methods);
  3396.           pop_obstacks ();
  3397.  
  3398.           TREE_TYPE (tmp) = unknown_type_node;
  3399. #if 0
  3400.           TREE_OVERLOADED (tmp) = DECL_OVERLOADED (*methods);
  3401. #endif
  3402.           TREE_NONLOCAL_FLAG (tmp) = 1;
  3403.           
  3404.           /* See comment above for a description of envelopes.  */
  3405.           closed_envelopes = tree_cons (tmp, class_value,
  3406.                         closed_envelopes);
  3407.           IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods)) = closed_envelopes;
  3408.         }
  3409. #else
  3410.       tree old = IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods));
  3411.  
  3412.       if (old && TREE_CODE (old) == TREE_LIST)
  3413.         tmp = tree_cons (DECL_NAME (*methods), *methods, old);
  3414.       else
  3415.         {
  3416.           /* Only complain if we shadow something we can access.  */
  3417.           if (old && (DECL_CLASS_CONTEXT (old) == current_class_type
  3418.               || ! TREE_PRIVATE (old)))
  3419.         /* Should figure out visibility more accurately.  */
  3420.         cp_warning_at ("member function `%D' shadows member `%s'", *methods,
  3421.                    IDENTIFIER_POINTER (DECL_NAME (old)));
  3422.           tmp = build_tree_list (DECL_NAME (*methods), *methods);
  3423.         }
  3424.  
  3425.       TREE_TYPE (tmp) = unknown_type_node;
  3426. #if 0
  3427.       TREE_OVERLOADED (tmp) = DECL_OVERLOADED (*methods);
  3428. #endif
  3429.       TREE_NONLOCAL_FLAG (tmp) = 1;
  3430.       IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods)) = tmp;
  3431. #endif
  3432.  
  3433.       tmp = *methods;
  3434.       while (tmp != 0)
  3435.         {
  3436.           DECL_PUBLIC (tmp) = 0;
  3437.           DECL_PROTECTED (tmp) = 0;
  3438.           DECL_PRIVATE (tmp) = 0;
  3439.           tmp = DECL_CHAIN (tmp);
  3440.         }
  3441.  
  3442.       methods++;
  3443.     }
  3444.     }
  3445.   SET_BINFO_MARKED (binfo);
  3446. }
  3447.  
  3448. /* Consolidate unique (by name) member functions.  */
  3449. static void
  3450. dfs_compress_decls (binfo)
  3451.      tree binfo;
  3452. {
  3453.   tree type = BINFO_TYPE (binfo);
  3454.   tree method_vec = CLASSTYPE_METHOD_VEC (type);
  3455.  
  3456.   if (method_vec != 0)
  3457.     {
  3458.       /* Farm out constructors and destructors.  */
  3459.       tree *methods = &TREE_VEC_ELT (method_vec, 1);
  3460.       tree *end = TREE_VEC_END (method_vec);
  3461.  
  3462.       for (; methods != end; methods++)
  3463.     {
  3464. #if NEW_CLASS_SCOPING
  3465.       /* This is known to be an envelope of the kind described before
  3466.          dfs_pushdecls.  */
  3467.       tree class_value = IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods));
  3468.       tree tmp = TREE_PURPOSE (class_value);
  3469. #else
  3470.       tree tmp = IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods));
  3471. #endif
  3472.  
  3473.       /* This was replaced in scope by somebody else.  Just leave it
  3474.          alone.  */
  3475.       if (TREE_CODE (tmp) != TREE_LIST)
  3476.         continue;
  3477.  
  3478.       if (TREE_CHAIN (tmp) == NULL_TREE
  3479.           && TREE_VALUE (tmp)
  3480.           && DECL_CHAIN (TREE_VALUE (tmp)) == NULL_TREE)
  3481.         {
  3482. #if NEW_CLASS_SCOPING
  3483.           TREE_PURPOSE (class_value) = TREE_VALUE (tmp);
  3484. #else
  3485.           IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods)) = TREE_VALUE (tmp);
  3486. #endif
  3487.         }
  3488.     }
  3489.     }
  3490.   CLEAR_BINFO_MARKED (binfo);
  3491. }
  3492.  
  3493. /* When entering the scope of a class, we cache all of the
  3494.    fields that that class provides within its inheritance
  3495.    lattice.  Where ambiguities result, we mark them
  3496.    with `error_mark_node' so that if they are encountered
  3497.    without explicit qualification, we can emit an error
  3498.    message.  */
  3499. void
  3500. push_class_decls (type)
  3501.      tree type;
  3502. {
  3503.   tree id;
  3504.   struct obstack *ambient_obstack = current_obstack;
  3505.  
  3506. #if 0
  3507.   tree tags = CLASSTYPE_TAGS (type);
  3508.  
  3509.   while (tags)
  3510.     {
  3511.       tree code_type_node;
  3512.       tree tag;
  3513.  
  3514.       switch (TREE_CODE (TREE_VALUE (tags)))
  3515.     {
  3516.     case ENUMERAL_TYPE:
  3517.       code_type_node = enum_type_node;
  3518.       break;
  3519.     case RECORD_TYPE:
  3520.       code_type_node = record_type_node;
  3521.       break;
  3522.     case CLASS_TYPE:
  3523.       code_type_node = class_type_node;
  3524.       break;
  3525.     case UNION_TYPE:
  3526.       code_type_node = union_type_node;
  3527.       break;
  3528.     default:
  3529.       my_friendly_abort (297);
  3530.     }
  3531.       tag = xref_tag (code_type_node, TREE_PURPOSE (tags),
  3532.               TYPE_BINFO_BASETYPE (TREE_VALUE (tags), 0));
  3533. #if 0 /* not yet, should get fixed properly later */
  3534.       pushdecl (make_type_decl (TREE_PURPOSE (tags), TREE_VALUE (tags)));
  3535. #else
  3536.       pushdecl (build_decl (TYPE_DECL, TREE_PURPOSE (tags), TREE_VALUE (tags)));
  3537. #endif
  3538.     }
  3539. #endif
  3540.  
  3541.   search_stack = push_search_level (search_stack, &search_obstack);
  3542.  
  3543.   id = TYPE_IDENTIFIER (type);
  3544.   if (IDENTIFIER_TEMPLATE (id) != 0)
  3545.     {
  3546. #if 0
  3547.       tree tmpl = IDENTIFIER_TEMPLATE (id);
  3548.       push_template_decls (DECL_ARGUMENTS (TREE_PURPOSE (tmpl)),
  3549.                TREE_VALUE (tmpl), 1);
  3550. #endif
  3551. #if NEW_CLASS_SCOPING
  3552.       overload_template_name (id, 1);
  3553. #else
  3554.       overload_template_name (id, 0);
  3555. #endif
  3556.     }
  3557.  
  3558.   /* Push class fields into CLASS_VALUE scope, and mark.  */
  3559.   dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarkedp);
  3560.  
  3561.   /* Compress fields which have only a single entry
  3562.      by a given name, and unmark.  */
  3563.   dfs_walk (TYPE_BINFO (type), dfs_compress_decls, markedp);
  3564.  
  3565. #if NEW_CLASS_SCOPING
  3566.   /* Open up all the closed envelopes and push the contained decls into
  3567.      class scope.  */
  3568.   while (closed_envelopes)
  3569.     {
  3570.       tree new = TREE_PURPOSE (closed_envelopes);
  3571.       tree id;
  3572.  
  3573.       /* This is messy because the class value may be a *_DECL, or a
  3574.      TREE_LIST of overloaded *_DECLs or even a TREE_LIST of ambiguous
  3575.      *_DECLs.  The name is stored at different places in these three
  3576.      cases.  */
  3577.       if (TREE_CODE (new) == TREE_LIST)
  3578.     {
  3579.       if (TREE_PURPOSE (new) != NULL_TREE)
  3580.         id = TREE_PURPOSE (new);
  3581.       else
  3582.         {
  3583.           tree node = TREE_VALUE (new);
  3584.  
  3585.           while (TREE_CODE (node) == TREE_LIST)
  3586.         node = TREE_VALUE (node);
  3587.           id = DECL_NAME (node);
  3588.         }
  3589.     }
  3590.       else
  3591.     id = DECL_NAME (new);
  3592.  
  3593.       /* Install the original class value in order to make
  3594.      pushdecl_class_level work correctly.  */
  3595.       IDENTIFIER_CLASS_VALUE (id) = TREE_VALUE (closed_envelopes);
  3596.       if (TREE_CODE (new) == TREE_LIST)
  3597.     push_class_level_binding (id, new);
  3598.       else
  3599.     pushdecl_class_level (new);
  3600.       closed_envelopes = TREE_CHAIN (closed_envelopes);
  3601.     }
  3602. #endif
  3603.   current_obstack = ambient_obstack;
  3604. }
  3605.  
  3606. #if !NEW_CLASS_SCOPING
  3607. static void
  3608. dfs_popdecls (binfo)
  3609.      tree binfo;
  3610. {
  3611.   tree type = BINFO_TYPE (binfo);
  3612.   tree fields = TYPE_FIELDS (type);
  3613.   tree method_vec = CLASSTYPE_METHOD_VEC (type);
  3614.  
  3615.   while (fields)
  3616.     {
  3617.       if (DECL_NAME (fields) == NULL_TREE
  3618.       && TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE)
  3619.     {
  3620.       dfs_popdecls (TYPE_BINFO (TREE_TYPE (fields)));
  3621.     }
  3622.       else if (DECL_NAME (fields))
  3623.     IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) = NULL_TREE;
  3624.       fields = TREE_CHAIN (fields);
  3625.     }
  3626.   if (method_vec != 0)
  3627.     {
  3628.       tree *methods = &TREE_VEC_ELT (method_vec, 0);
  3629.       tree *end = TREE_VEC_END (method_vec);
  3630.  
  3631.       /* Clear out ctors and dtors.  */
  3632.       if (*methods)
  3633.     IDENTIFIER_CLASS_VALUE (TYPE_IDENTIFIER (type)) = NULL_TREE;
  3634.  
  3635.       for (methods += 1; methods != end; methods++)
  3636.     IDENTIFIER_CLASS_VALUE (DECL_NAME (*methods)) = NULL_TREE;
  3637.     }
  3638.  
  3639.   SET_BINFO_MARKED (binfo);
  3640. }
  3641. #endif
  3642.  
  3643. void
  3644. pop_class_decls (type)
  3645.      tree type;
  3646. {
  3647. #if !NEW_CLASS_SCOPING
  3648.   tree binfo = TYPE_BINFO (type);
  3649.  
  3650.   /* Clear out the IDENTIFIER_CLASS_VALUE which this
  3651.      class may have occupied, and mark.  */
  3652.   dfs_walk (binfo, dfs_popdecls, unmarkedp);
  3653.  
  3654.   /* Unmark.  */
  3655.   dfs_walk (binfo, dfs_unmark, markedp);
  3656. #else
  3657.   /* We haven't pushed a search level when dealing with cached classes,
  3658.      so we'd better not try to pop it.  */
  3659.   if (search_stack)
  3660. #endif
  3661.     search_stack = pop_search_level (search_stack);
  3662. }
  3663.  
  3664. static int
  3665. bfs_unmark_finished_struct (binfo, i)
  3666.      tree binfo;
  3667.      int i;
  3668. {
  3669.   if (i >= 0)
  3670.     binfo = BINFO_BASETYPE (binfo, i);
  3671.  
  3672.   if (BINFO_NEW_VTABLE_MARKED (binfo))
  3673.     {
  3674.       tree decl, context;
  3675.  
  3676.       if (TREE_VIA_VIRTUAL (binfo))
  3677.     binfo = binfo_member (BINFO_TYPE (binfo),
  3678.                   CLASSTYPE_VBASECLASSES (current_class_type));
  3679.  
  3680.       decl = BINFO_VTABLE (binfo);
  3681.       context = DECL_CONTEXT (decl);
  3682.       DECL_CONTEXT (decl) = 0;
  3683.       if (write_virtuals >= 0
  3684.       && DECL_INITIAL (decl) != BINFO_VIRTUALS (binfo))
  3685.     DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE,
  3686.                     BINFO_VIRTUALS (binfo));
  3687.       finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
  3688.       DECL_CONTEXT (decl) = context;
  3689.     }
  3690.   CLEAR_BINFO_VTABLE_PATH_MARKED (binfo);
  3691.   CLEAR_BINFO_NEW_VTABLE_MARKED (binfo);
  3692.   return 0;
  3693. }
  3694.  
  3695. void
  3696. unmark_finished_struct (type)
  3697.      tree type;
  3698. {
  3699.   tree binfo = TYPE_BINFO (type);
  3700.   bfs_unmark_finished_struct (binfo, -1);
  3701.   breadth_first_search (binfo, bfs_unmark_finished_struct, bfs_marked_vtable_pathp);
  3702. }
  3703.  
  3704. void
  3705. print_search_statistics ()
  3706. {
  3707. #ifdef GATHER_STATISTICS
  3708.   if (flag_memoize_lookups)
  3709.     {
  3710.       fprintf (stderr, "%d memoized contexts saved\n",
  3711.            n_contexts_saved);
  3712.       fprintf (stderr, "%d local tree nodes made\n", my_tree_node_counter);
  3713.       fprintf (stderr, "%d local hash nodes made\n", my_memoized_entry_counter);
  3714.       fprintf (stderr, "fields statistics:\n");
  3715.       fprintf (stderr, "  memoized finds = %d; rejects = %d; (searches = %d)\n",
  3716.            memoized_fast_finds[0], memoized_fast_rejects[0],
  3717.            memoized_fields_searched[0]);
  3718.       fprintf (stderr, "  memoized_adds = %d\n", memoized_adds[0]);
  3719.       fprintf (stderr, "fnfields statistics:\n");
  3720.       fprintf (stderr, "  memoized finds = %d; rejects = %d; (searches = %d)\n",
  3721.            memoized_fast_finds[1], memoized_fast_rejects[1],
  3722.            memoized_fields_searched[1]);
  3723.       fprintf (stderr, "  memoized_adds = %d\n", memoized_adds[1]);
  3724.     }
  3725.   fprintf (stderr, "%d fields searched in %d[%d] calls to lookup_field[_1]\n",
  3726.        n_fields_searched, n_calls_lookup_field, n_calls_lookup_field_1);
  3727.   fprintf (stderr, "%d fnfields searched in %d calls to lookup_fnfields\n",
  3728.        n_outer_fields_searched, n_calls_lookup_fnfields);
  3729.   fprintf (stderr, "%d calls to get_base_type\n", n_calls_get_base_type);
  3730. #else
  3731.   fprintf (stderr, "no search statistics\n");
  3732. #endif
  3733. }
  3734.  
  3735. void
  3736. init_search_processing ()
  3737. {
  3738.   gcc_obstack_init (&search_obstack);
  3739.   gcc_obstack_init (&type_obstack);
  3740.   gcc_obstack_init (&type_obstack_entries);
  3741.  
  3742.   /* This gives us room to build our chains of basetypes,
  3743.      whether or not we decide to memoize them.  */
  3744.   type_stack = push_type_level (0, &type_obstack);
  3745.   _vptr_name = get_identifier ("_vptr");
  3746. }
  3747.  
  3748. void
  3749. reinit_search_statistics ()
  3750. {
  3751.   my_memoized_entry_counter = 0;
  3752.   memoized_fast_finds[0] = 0;
  3753.   memoized_fast_finds[1] = 0;
  3754.   memoized_adds[0] = 0;
  3755.   memoized_adds[1] = 0;
  3756.   memoized_fast_rejects[0] = 0;
  3757.   memoized_fast_rejects[1] = 0;
  3758.   memoized_fields_searched[0] = 0;
  3759.   memoized_fields_searched[1] = 0;
  3760.   n_fields_searched = 0;
  3761.   n_calls_lookup_field = 0, n_calls_lookup_field_1 = 0;
  3762.   n_calls_lookup_fnfields = 0, n_calls_lookup_fnfields_1 = 0;
  3763.   n_calls_get_base_type = 0;
  3764.   n_outer_fields_searched = 0;
  3765.   n_contexts_saved = 0;
  3766. }
  3767.